Can't wrap your head around wpf binding

My scenario: A wpf form has a textbox and a wpf datagrid tool . When text is entered into a textbox, my service returns items IEnumerable<TranslationItem>

. I want my datagrid to show the result of this service.

I tried taking a walk, but I can't get heads or tails. I'm just starting to learn WPF and most of the terms I use elude me.
I'm going to say that I should return the service result in an ObservableCollection, not a sweat. But then I want to bind it somehow to my datagrid. How can i do this? How does the network know which columns will be created?

0


a source to share


4 answers


What I'm going for is that I have to put my service result in an ObservableCollection, no sweat. But then I want to bind it somehow to my datagrid. How can i do this?

The easiest way is to set the ItemsSource DataGrid property to ObservableCollection.

How does the grid know which columns will be created?



The DataGrid reflects the objects in this collection and creates a column for each public property it finds. See here for details .

If you set the ItemsSource property directly, it won't be a wpf binding. Here are three links that I found helpful when I started data binding in WPF.

Bea Stollnitz: What does "{Binding}" mean? MSDN WPF Data Binding FAQ
: Data Binding Practical Topics

+3


a source


While ObservableCollection can be used for this, depending on how it is used, you will not get any benefit from it. The key feature of ObservableCollection is that it implements INotifyCollectionChanged. What this interface does is a mechanism for notifying that the user interface has changed a property. Since ObservableCollection already implements this if you bind your DataGrid object, ListBox, ItemsControl, etc. ItemSource to a collection of this type, it will automatically update the UI whenever an item is added or removed. / Moved / Moved / Reset. Because of this, every time you want to update the collection with a new IEnumerable result set, you will have to first clear the collection and then add new results.

However, there is another option that I would recommend in the ObservableCollection in this case. It should use something called ObjectDataProvider. By using this, we can avoid the code entirely, and it is much cleaner overall. So we have our service somewhere, in this case in my Window.xaml.cs

public class TranslationService
{
    public IEnumerable<string> Translate(string s)
    {
        return s.ToCharArray().Select(c => c.ToString());
    }
}

      

Like the service you are describing, it takes a string from a textbox and returns an IEnumerable. Now in XAML we can use this service and make calls to it.

In window decoders, we'll add the namespace that the service resides in:

 xmlns:local="clr-namespace:WpfApplication4"

      

Now, in our Window.Resources (or UserControl or elsewhere), we can refer to our service. After we have exposed our service as a resource, we can create an ObjectDataProvider that provides the translation method we want to use.



<Window.Resources>
    <local:TranslationService x:Key="MyTranslationService" />
    <ObjectDataProvider x:Key="MyProvider"
                        ObjectInstance="{StaticResource MyTranslationService}"
                        MethodName="Translate">
        <ObjectDataProvider.MethodParameters>
            ""
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</Window.Resources>

      

The ObjectDataProvider is bound to our service and calls the Translate method with a String parameter. Now all we have to do is make it respond to our text box.

We can do this using some of the Binding properties. We want our TextProperty in the TextBox to bind to the ObjectDataProvider, so we set the Source property to point to it. The part of the ObjectDataProvider that we want to bind in the Path is the MethodParameter. We now bind it to Bind directly to the source of this property and only navigate one way, which means that the parameter of the ObjectDataProvider method will not update the TextBox's text. Finally, we can set the UpdateSourceTrigger to PropertyChanged by specifying the binding to set the source we are binding to in the object's data provider whenever there is any change to the text.

<StackPanel>
        <TextBox TextChanged="OnTextChanged"
            Text="{Binding Source={StaticResource MyProvider}, Path=MethodParameters[0], BindsDirectlyToSource=True, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}" />
        <ListBox ItemsSource="{Binding Source={StaticResource MyProvider}}" />
    </StackPanel>

      

All that's left is to set the ItemsSource to a Grid, or a simple ListBox in this case.

Regarding the last part on the DataGrid: If you are using the WPFToolkit data grid, it has an auto-generation feature that can be set via properties, and you can find more information on that here .

+2


a source


You are setting the DataSource (or even DataContext) of the grid to your Observable collection.

I'm not familiar with this data grid, but most grids have options to either expose all the public type properties in the Observable Collection as columns, or explicitly set the layout of the columns in XAML and one of the column definition properties is a property of the object used for the column data ...

eg. with Infragistics data network

                <igDP:Field Name="OrderSize" Label="Order Size">
                    <igDP:Field.Settings >
                        <igDP:FieldSettings CellWidth="75">
                            <igDP:FieldSettings.EditorStyle>
                                <Style TargetType="{x:Type Editors:ValueEditor}" >
                                    <Style.Setters>
                                        <Setter Property="Format" Value="#,##0"/>
                                    </Style.Setters>
                                </Style>
                            </igDP:FieldSettings.EditorStyle>
                        </igDP:FieldSettings>
                    </igDP:Field.Settings>
                </igDP:Field>

      

The name is where you set the property for the used object.

0


a source


your grid can either build columns directly, or you can specify the column types you want. If you watch this video it will explain it. This is for VS2010, but the basic principles are the same for VS2008, although the implementation is slightly different as it is not quite integrated.

As for binding, assign an ObservableCollection that holds your items in the ItemsSource property of the grid.

0


a source







All Articles