问题
I have a DataGrid
with two DataGridComboBoxColumn
s 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)
回答1:
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.
回答2:
Right so, I figured it out.
Use SelectedValueBinding={Binding object} and SelectedValuePath="" That fixed it for me.
WPF: Databinding with DataGridComboBoxColumn
回答3:
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}"
/>
来源:https://stackoverflow.com/questions/12040164/selected-item-not-displayed-in-the-datagridcomboboxcolumn