0

I have a DataGrid with two DataGridComboBoxColumns set in the XAML (copied from here):

<DataGrid x:Name="joinGrid" AutoGenerateColumns="False" CanUserAddRows="True">
                <DataGrid.Columns>
                    <DataGridComboBoxColumn>
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="IsDropDownOpen" Value="True" />
                                <Setter Property="ItemsSource" Value="{Binding Path=TableAColumns}" />
                                <Setter Property="ItemTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding}"></TextBlock>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle >
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Path=TableAColumns}" />
                                <Setter Property="IsDropDownOpen" Value="True" />
                                <Setter Property="ItemTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding}"></TextBlock>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>

                    <DataGridComboBoxColumn>
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="IsDropDownOpen" Value="True" />
                                <Setter Property="ItemsSource" Value="{Binding Path=TableBColumns}" />
                                <Setter Property="ItemTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding}"></TextBlock>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                                <Setter Property="ItemsSource" Value="{Binding Path=TableBColumns}" />
                                <Setter Property="IsDropDownOpen" Value="True" />
                                <Setter Property="ItemTemplate">
                                    <Setter.Value>
                                        <DataTemplate>
                                            <TextBlock Text="{Binding}"></TextBlock>
                                        </DataTemplate>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>
                </DataGrid.Columns>
            </DataGrid>

with few exceptions because honestly i do not understand what should go in the missing porperties. I am trying to bind the columns to lists of strings contained in an entity class:

class JoinBlockDTO
{
    public List<string> TableAColumns { get; set; }
    public List<string> TableBColumns { get; set; }
}

In my code behind, i set the grid's ItemsSource:

DataGrid dg = (DataGrid)GetTemplateChild("joinGrid");

List<JoinBlockDTO> l = new List<JoinBlockDTO>();
List<string> colAList = (from DataRowView row in sourceA
                         select row.Row.Field<string>(0)).ToList();
List<string> colBList = (from DataRowView row in sourceB
                         select row.Row.Field<string>(0)).ToList();

((DataGridComboBoxColumn)dg.Columns[0]).ItemsSource = colAList; //doesn't work without this
((DataGridComboBoxColumn)dg.Columns[1]).ItemsSource = colBList; //doesn't work without this
l.Add (new JoinBlockDTO(){TableAColumns = colAList, TableBColumns = colBList});
dg.ItemsSource = l;

All this, initially, renders a 2 x 2 grid with all blank cells. I click twice to see a drop-down with the list of strings bound properly. However, when i select a value from the drop-down and shift the focus outside, the cell is left blank. Can someone point out what should be added to the XAML or modified? Is there a simpler way to do this binding? I have read numerous posts about this combo-box column binding but could not understand what was going on. (Using VS2010)

Community
  • 1
  • 1
badmaash
  • 4,775
  • 7
  • 46
  • 61
  • could you explain what you want to have? Cuz here you said more about what you have done. Than I'll try to help you. There's no big deal should be with combobox columns – Artiom Aug 21 '12 at 05:13
  • The problem is that when i select an item from the drop-down and shift the focus outside of the cell, the selected value is not displayed in the cell in the form of a `TextBlock`. I want the cell to display the selected value in the form of a `TextBlock`. – badmaash Aug 22 '12 at 08:57
  • Try adding a SelectedItemBinding in xaml – Nicholas Aug 15 '13 at 08:12

3 Answers3

1

Right so, I figured it out.

Use SelectedValueBinding={Binding object} and SelectedValuePath="" That fixed it for me.

WPF: Databinding with DataGridComboBoxColumn

Community
  • 1
  • 1
Nicholas
  • 783
  • 2
  • 7
  • 25
0

Perhaps your VM doesn't implement INotifyPropertyChanged interface.

Here is an example:

<Window x:Class="wpfProj.MainWindow"
        ...
        d:DataContext="{d:DesignInstance wpfProj:MainViewModel}">

    <Grid >
        <Grid.Resources>
            <wpfProj:BindingProxy x:Key="proxy" Data="{Binding}"/>
        </Grid.Resources>
        <DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Path=Persons}">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Binding="{Binding Path=Name}" Width="*"/>
                <DataGridComboBoxColumn Header="Sex" Width="*" ItemsSource="{Binding Source={StaticResource proxy}, Path=Data.SexList}"
                                        SelectedItemBinding="{Binding Path=Sex}"/>
                <DataGridComboBoxColumn Header="Sex" Width="*" ItemsSource="{Binding Source={x:Static wpfProj:DataCollection.Instance}, Path=SexList}"
                                        SelectedItemBinding="{Binding Path=Sex}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

I placed two "Sex" columns just to show two ways to bind to source. In first case, SexList is a part of ViewModel (DataContext), that's why I used proxy. In the second case it's binded to the singleton's property.

Sex property:

    public string Sex
    {
        get { return _sex; }
        set
        {
            _sex = value;
            OnPropertyChanged("Sex");
        }
    }

And the proxy class (I've found it in the Internet, don't remember the link to the author's page)

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

Hope it helps. Here is the sample I've uploaded.

Artiom
  • 7,694
  • 3
  • 38
  • 45
0

this will help u

use "ObservableCollection"List to auto INotifyPropertyChanged

 <DataGrid x:Name="myDataGridTeacher" 
                  ItemsSource="{Binding ObservableCollectionList}" >

 <DataGridTemplateColumn Width="*" Header="MyHeader"  >
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate >

                            <TextBlock Text="{Binding Material_Name.Name}" 
                                  />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>

                    <DataGridTemplateColumn.CellEditingTemplate>
                        <DataTemplate>
                            <ComboBox  
                                       ItemsSource="{Binding Material_Name}" 
                                       DisplayMemberPath="Name"

                                />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellEditingTemplate>

                </DataGridTemplateColumn>

 </DataGrid>

ItemsSource="{Binding Material_Name}" is List in "ObservableCollectionList"

<TextBlock Text="{Binding Material_Name.Name}" 
                                      />