WPF: 数据绑定(Halcon)

本实例完全是翻译Halcon 13.0中的实例代码BindingWPF(WPF新手)。

1)构建编程环境

    1.1)参照实例代码,在VS2017 Community中选择WPF窗体模式(WPF应用(.Net Framework),同时选择框架.Net Framework 3.5),选择代码保存的位置,直接生成即可。

    1.2)这一步,可以选编译试试,选择Run,看看代码是否能正常生成,运行。

    1.3)添加引用,我们需要选择Halcondotnet 3.5版本的库。同时打开文件MainWindow.xaml添加引用

xmlns:HalconDotnet="clr-namespace:HalconDotNet;assembly=halcondotnet"
xmlns:local="clr-namespace:MyBinding1"

上面MyBinding1使我们工程的名字。

    1.4)更改窗体大小:

Title="MainWindow" Height="800" Width="600" MinWidth="450" MinHeight="400">

再次测试,如同1.2)步,看是否能正常运行。

2)准备数据转换类

    在运行源代码时候,这个转换类会有Exception显示,原因是解析的时候出错,把

string[] ImagePartArg = value.ToString().Split(';');
换成
string[] ImagePartArg = value.ToString().Split(',');

即可。最终完整代码为:

public class ImagePartDecimalPlaceConverter : IValueConverter
{
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                //seems just return value is also ok
                string[] ImagePartArg = value.ToString().Split(',');
                Console.WriteLine(value.ToString());

                string shortForm = ImagePartArg[0] + ','
                                   + ImagePartArg[1] + ','
                                   + ImagePartArg[2] + ','
                                   + ImagePartArg[3];
                return shortForm;
            }
            catch (Exception)
            {
                // In error case, just return the input value, do nothing
                return value.ToString();
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            // Nothing to do in set mode
            return value.ToString();
        }
 }

IValueConverter必须要实现Convert和ConvertBack两个函数。

3)准备Resource

    打开App.xaml文件,把这个转换类作为Resource作为App的资源,添加以下代码:

<Application.Resources>
        <local:ImagePartDecimalPlaceConverter x:Key="ImagePart"/>
</Application.Resources>

我原来想把这部分同源代码一样放入MainWindow.xaml中作为<Window.Resources></Window.Resources>的一部分,后面在调试时发现报错,就改到放到App.xaml文件中。对命名空间这块可能还是没整明白。

4)设置Grid布局部分

    整体分为两行一列,第一行放按钮及相关Label等,第二行放置图像及两个Slider(竖直和水平各一个):

<Grid.RowDefinitions>
     <RowDefinition MaxHeight="200"></RowDefinition>
     <RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
     <ColumnDefinition/>
</Grid.ColumnDefinitions>

以下为第一行的子网格(又分为6行5列):

<Grid Grid.Row="0" Grid.Column="0" MaxHeight="150">
            <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>  
</Grid>

接下来是第二行内容,分为两行两列:

<Grid Grid.Row="1" Grid.Column="0">
            <Grid.RowDefinitions>
                <RowDefinition MaxHeight="25"></RowDefinition>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition MaxWidth="25"></ColumnDefinition>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
</Grid>

至此,网格设计完成(都是直接拷贝的)。这些网格只是方便后面对其它控件布置。运行代码,界面上没看到什么特别的。

5)在Grid(0,0)部分添加4个按钮,用于加载4张不同的图像:

<Button Content="Fabrik"    HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" Width="75" Click="Button_Click_Fabrik"/>
<Button Content="Patras"    HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="0" Grid.Column="2" Width="75" Click="Button_Click_Patras"/>
<Button Content="Atoms"     HorizontalAlignment="Left" VerticalAlignment="Center" Width="75" Grid.Row="0" Grid.Column="3" Click="Button_Click_Atoms"/>
<Button Content="PCBLayout" HorizontalAlignment="Left" VerticalAlignment="Center" Width="75" Grid.Row="0" Grid.Column="4" Click="Button_Click_PCBLayout"/>

以第一个按钮为例,按钮文本=Fabik,接下来是对其格式,放置在子网格的(0,1)处,对应的事件Button_Click_Fabrik。

打开MainWindow.xaml.cs文件,添加4个按钮的处理事件:

private void Button_Click_Fabrik(object sender, RoutedEventArgs e)
{
   hwindow.HDisplayCurrentObject = new HImage("fabrik");
}

private void Button_Click_Patras(object sender, RoutedEventArgs e)
{
   hwindow.HDisplayCurrentObject = new HImage("patras");
}

private void Button_Click_Atoms(object sender, RoutedEventArgs e)
{
   hwindow.HDisplayCurrentObject = new HImage("atoms");
}

private void Button_Click_PCBLayout(object sender, RoutedEventArgs e)
{
   hwindow.HDisplayCurrentObject = new HImage("pcb_layout");
   HRegion region = ((HImage)hwindow.HDisplayCurrentObject).Threshold(0, 50.0);
   HRegion connected_region = region.Connection();
   hwindow.HDisplayCurrentObject = connected_region;
}
4个按钮分别加载4张不同的图像,其中PCBLayout部分,加载图像后二值化,找边并显示边界图像。

VS会提示很多错误,主要由于Halcon引起的,在文件开始部分先添加Halcon的引用:

using HalconDotNet;

其它会显示hwindow无法识别,这是由于我们还没有把窗体hwindow添加进去,这一步暂时放一放。

6)接下来添加Label,注意它们在Grid中的位置:

<Label  Content="Images:"   HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="0" Grid.Column="0" />
<Label Content="WindowSize:"      HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Grid.Column="0" />
<Label Content="ImagePart:"       HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Grid.Column="0" />
<Label Content="HMoveContent:"    HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="3" Grid.Column="0" />
<Label Content="HKeepAspectRatio" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="4" Grid.Column="0" />
<Label Content="HZoomFactor:"     HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="5" Grid.Column="0" />

7)添加其它相关控件:

<TextBlock Name="WindowSize"       HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="1" Grid.Column="1"
                       Text="{Binding ElementName=hwindow, Path=WindowSize, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox   Name="ImagePart"        HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="2" Grid.Column="1"
                       Text="{Binding ElementName=hwindow, Path=HImagePart, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource ImagePart}}"/>
<CheckBox  Name="HMoveContent"     HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="3" Grid.Column="1"
                       IsChecked="{Binding ElementName=hwindow, Path=HMoveContent}"/>
<CheckBox  Name="HKeepAspectRatio" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="4" Grid.Column="1"
                       IsChecked="{Binding ElementName=hwindow, Path=HKeepAspectRatio}"/>
<Slider    Name="HZoomFactor"      IsSnapToTickEnabled="True" VerticalAlignment="Center" Grid.Row="5" Grid.Column="1"
                       Value="{Binding ElementName=hwindow, Path=HZoomFactor, UpdateSourceTrigger=PropertyChanged}" Grid.ColumnSpan="2" Minimum="1.01" Maximum="9.99"
                       TickFrequency="0.01"/>
<TextBlock Name="HZoomFactorValue" HorizontalAlignment="Left" VerticalAlignment="Center" Grid.Row="5" Grid.Column="3"
                       Text="{Binding ElementName=HZoomFactor, Path=Value}"/>

其中,WindowSize显示hwindow的大小;

ImagePart显示图像大小,它与HImagePart绑定,当这个属性改变时这个值也跟着改变;

HMoveContent设置图像位置是否与鼠标移动相关联,前提是鼠标需要放到图像上;

HKeepAspectRatio设置图像开始显示时是否完全填充图像框;

HZoomFactor图像缩放,并把缩放的比例大小放到HZoomFactorValue文本当中。

8)添加窗体:

8.1)进入窗体设计界面,点击左上角的‘工具箱’;

8.2)右键点击’常用WPF控件’,选择’选择项...’;

8.3)进入到WPF组件界面,点击’浏览...’找到HalconDotnet (3.5版本),加载;

8.4)这时候在工具箱中能看到HSmartWindowControlWPF及HWindowControlWPF,选择前一个并拖到主界面下边中间位置,实际就是Grid(1,1)位置,设置控件名称为hwindow。第5)步报错就是由于它引起的,现在没有了。

9)添加窗体及两个Slider:

<HalconDotnet:HSmartWindowControlWPF Name="hwindow" Width="{Binding ElementName=WidthSlider, Path=Value}"
                                     Height="{Binding ElementName=HeightSlider, Path=Value}" Loaded="HSmartWindowControlWPF_Loaded"
                                     Grid.Row="1" Grid.Column="1"/>
            
<Slider Name="HeightSlider" Minimum="20" Maximum="512" Value="512" TickFrequency="1" IsSnapToTickEnabled="True" Grid.Row="1" Grid.Column="0" Orientation="Vertical"/>
<Slider Name="WidthSlider"  Minimum="20" Maximum="512" Value="512" TickFrequency="1" IsSnapToTickEnabled="True" Grid.Row="0" Grid.Column="1" />

上面窗体的宽度与水平Slider的相关联,高度与竖直Slider相关联,同时在窗体加载时,同时加载图像“fabrik”,并计算WindowSize和ImagePart两个参数。

10)运行代码,改变两个Slider的位置,会看到图像大小也跟着改变。

 

猜你喜欢

转载自blog.csdn.net/huan_126/article/details/80180647