tags:

views:

1147

answers:

2

I have a DataGrid template column with ComboBox. When I select a value and press enter the bound data is not updated (I see empty cell).

XAML:

<Window x:Class="WpfGrid2.Window2"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:sys="clr-namespace:System;assembly=mscorlib"
  xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WpfToolkit"
  >

    <Window.Resources>
        <x:Array x:Key="people" Type="sys:Object" />

        <x:Array x:Key="knownLastNames" Type="sys:String">
            <sys:String>Smith</sys:String>
            <sys:String>Johnson</sys:String>
            <sys:String>Williams</sys:String>
        </x:Array>
    </Window.Resources>

    <StackPanel>
        <dg:DataGrid x:Name="_grid" ItemsSource="{DynamicResource people}" CanUserAddRows="True" AutoGenerateColumns="False">
            <dg:DataGrid.Columns>

                <dg:DataGridTemplateColumn Header="LastName" MinWidth="100">
                    <dg:DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{DynamicResource knownLastNames}" SelectedItem="{Binding LastName}"></ComboBox>
                        </DataTemplate>
                    </dg:DataGridTemplateColumn.CellEditingTemplate>
                    <dg:DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding LastName}" />
                        </DataTemplate>
                    </dg:DataGridTemplateColumn.CellTemplate>
                </dg:DataGridTemplateColumn>

            </dg:DataGrid.Columns>
        </dg:DataGrid>

        <Button>test</Button>
    </StackPanel>
</Window>

Code-Behind:

namespace WpfGrid2
{
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();

            List<Person> people = new List<Person>();
            this.Resources["people"] = people;
        }
    }
}

If I change ComboBox to TextBox, it works fine

<TextBox Text="{Binding LastName}" />

What is wrong?

A: 

I don't know if this is a feasible solution to your problem, but if you change the ItemsSource binding of the Combo-Box to a StaticResource, the binding works.

...

<ComboBox ItemsSource="{StaticResource knownLastNames}" ... />

...

I am pretty sure that what is happening is that when the ComboBox is unloaded (when the EditTemplate is unloaded due to submitting the new record), the DynamicResource attempts to lookup the resource again, and fails (because the ComboBox is no longer in the visual tree, it won't find the resource defined above it in the visual tree). This will set the ItemsSource to null, and also set the SelectedItem to null, thus setting LastName to null.

With a StaticResource, the collection is only searched for once, before the ComboBox is shown, so it is not reset to null.

Abe Heidebrecht
Your solution works and explanation makes sence. Seems I need an other way to make ItemsSource updatable...
alex2k8
A: 

Another alternative (following the logic of the 'Abe Heidebrecht' answer) is to move 'knownLastNames' into Application.Resources. See point #3.

Dynamic resource lookup behavior

  1. The lookup process checks for the requested key within the resource dictionary defined by the element that sets the property.

  2. The lookup process then traverses the logical tree upward, to the parent element and its resource dictionary. This continues until the root element is reached.

  3. Next, application resources are checked. Application resources are those resources within the resource dictionary that is defined by the Application object for your WPF application.

  4. Theme resource dictionary is checked, for the currently active theme. If the theme changes at runtime, the value is reevaluated.

  5. System resources are checked.

alex2k8