WPF: Data Binding (Halcon)

This example is completely translating the example code in Halcon 13.0 BindingWPF (WPF newbie).

1) Build a programming environment

    1.1) Referring to the example code, select the WPF form mode in the VS2017 Community (WPF application (.Net Framework), and select the framework .Net Framework 3.5), select the location where the code is saved, and generate it directly.

    1.2) In this step, you can choose to compile and try, choose Run, and see if the code can be generated and run normally.

    1.3) To add a reference, we need to select the library of Halcondotnet 3.5 version. Also open the file MainWindow.xaml to add a reference

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

MyBinding1 above gives our project the name.

    1.4) Change the form size:

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

Test again, as in step 1.2), to see if it works properly.

2) Prepare the data conversion class

    When running the source code, this conversion class will show Exception, the reason is that there is an error in parsing, put

string[] ImagePartArg = value.ToString().Split(';');
replace with
string[] ImagePartArg = value.ToString().Split(',');

That's it. The final complete code is:

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 must implement the Convert and ConvertBack functions.

3) Prepare Resource

    Open the App.xaml file, use this conversion class as Resource as the resource of the App, and add the following code:

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

I originally wanted to put this part of the same source code into MainWindow.xaml as a part of <Window.Resources></Window.Resources>. Later, when I found an error during debugging, I changed it to the App.xaml file. Maybe you still don't understand the namespace.

4) Set the Grid layout section

    The whole is divided into two rows and one column. The first row is for buttons and related Labels, and the second row is for images and two Sliders (one vertically and one horizontally):

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

The following is the subgrid of the first row (in turn divided into 6 rows and 5 columns):

<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>

Next is the second line of content, divided into two rows and two columns:

<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>

At this point, the grid design is completed (all copied directly). These grids are just convenient for laying out other controls later. Run the code and see nothing special on the interface.

5) Add 4 buttons in the Grid(0,0) section for loading 4 different images:

<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"/>

Take the first button as an example, the button text = Fabik, the next is its format, placed at (0,1) of the subgrid, and the corresponding event Button_Click_Fabrik.

Open the MainWindow.xaml.cs file and add 4 button processing events:

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();
   window.HDisplayCurrentObject = connected_region;
}
The 4 buttons respectively load 4 different images, among which the PCBLayout part, after loading the image, binarize, find the edge and display the boundary image.

VS will prompt a lot of errors, mainly caused by Halcon, add a reference to Halcon at the beginning of the file:

using HalconDotNet;

Others will show that hwindow cannot be recognized. This is because we haven't added the form hwindow yet, so let's put this step aside for now.

6) Next add the Labels, paying attention to their position in the 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) Add other related controls:

<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}"/>

Among them, WindowSize shows the size of hwindow;

ImagePart displays the image size, which is bound to HImagePart, and this value changes when this property changes;

HMoveContent sets whether the image position is associated with mouse movement, provided that the mouse needs to be placed on the image;

HKeepAspectRatio sets whether the image box is completely filled when the image starts to display;

The HZoomFactor image is scaled and the scaled size is placed in the HZoomFactorValue text.

8) Add form:

8.1) Enter the form design interface, click 'toolbox' in the upper left corner;

8.2) Right-click on 'Common WPF Controls' and select 'Select Items...';

8.3) Enter the WPF component interface, click 'Browse...' to find HalconDotnet (version 3.5), and load it;

8.4) At this time, you can see HSmartWindowControlWPF and HWindowControlWPF in the toolbox, select the previous one and drag it to the middle position at the bottom of the main interface, which is actually the Grid (1,1) position, and set the control name to hwindow. 5) The error reported in step 5 is caused by it, and now there is no more.

9) Add a form and two Sliders:

<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" />

The width of the above form is associated with the horizontal Slider, and the height is associated with the vertical Slider. At the same time, when the form is loaded, the image "fabrik" is loaded at the same time, and the two parameters WindowSize and ImagePart are calculated.

10) Run the code, change the position of the two Sliders, and you will see that the image size also changes.

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325644321&siteId=291194637