如何绑定DataGrid到更多的集合?
How to bind DataGrid to more collections?
我有一个绑定到 ObservableCollection 的 DataGrid (StoredSequences<Sequence>
):
<DataGrid ItemsSource="{Binding StoredSequences}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ID}" >
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding NameEnglish}" >
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
序列模型:
public class Sequence : INotifyPropertyChanged
{
public Sequence() { }
private int _id;
public int ID
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("ID");
}
}
private string _nameEnglish;
public string NameEnglish
{
get
{
return _nameEnglish;
}
set
{
_nameEnglish = value;
OnPropertyChanged("NameEnglish");
}
}
private int _value;
public int Value
{
get
{
return _value;
}
set
{
_value= value;
OnPropertyChanged("Value");
}
}
private string _category;
public string Category
{
get
{
return _category;
}
set
{
_category = value;
OnPropertyChanged("Category");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我想在网格的最后两列中添加两个 ComboBox,ItemsSource 绑定到其他 ObservableCollections(Values<int>
和 Categories<string>
在 ViewModel 中生成)。我可以添加文本框,因为 Sequence
包含 Value
和 Category
,但我希望用户能够 select 项目。我试过这个:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox1" ItemsSource="{Binding Values}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox2" ItemsSource="{Binding Categories}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
问题是组合框是空的。这是收到的错误之一:
System.Windows.Data Error: 40 : BindingExpression path error: 'Values' property not found on 'object' ''Sequence' (HashCode=31195541)'. BindingExpression:Path=Values; DataItem='Sequence' (HashCode=31195541); target element is 'ComboBox' (Name=ComboBox1'); target property is 'ItemsSource' (type 'IEnumerable')
将 DataGrid 绑定到更多集合的正确方法是什么?或者如何在 CellEdit 和 TextBox 上显示组合框?
您可以从错误消息中看出绑定失败,因为框架无法在 Sequence 类型的对象上找到 Values 和 Categories 属性。发生这种情况是因为您的 DataGrid 中的每一行都有底层序列作为其 DataContext。
如果您不想将 Values 和 Categories 集合添加到 Sequence 对象,那么您需要做的是更改您的 Bindings,以便它们绑定到父 DataContext,而不是行 DataContext。
试试这个例子,它将绑定重定向到 DataGrid 的 DataContext:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox2" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.Categories}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
我有一个绑定到 ObservableCollection 的 DataGrid (StoredSequences<Sequence>
):
<DataGrid ItemsSource="{Binding StoredSequences}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding ID}" >
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding NameEnglish}" >
<DataGridTextColumn.ElementStyle>
<Style>
<Setter Property="TextBlock.TextWrapping" Value="Wrap" />
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
序列模型:
public class Sequence : INotifyPropertyChanged
{
public Sequence() { }
private int _id;
public int ID
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("ID");
}
}
private string _nameEnglish;
public string NameEnglish
{
get
{
return _nameEnglish;
}
set
{
_nameEnglish = value;
OnPropertyChanged("NameEnglish");
}
}
private int _value;
public int Value
{
get
{
return _value;
}
set
{
_value= value;
OnPropertyChanged("Value");
}
}
private string _category;
public string Category
{
get
{
return _category;
}
set
{
_category = value;
OnPropertyChanged("Category");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
我想在网格的最后两列中添加两个 ComboBox,ItemsSource 绑定到其他 ObservableCollections(Values<int>
和 Categories<string>
在 ViewModel 中生成)。我可以添加文本框,因为 Sequence
包含 Value
和 Category
,但我希望用户能够 select 项目。我试过这个:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox1" ItemsSource="{Binding Values}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox2" ItemsSource="{Binding Categories}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
问题是组合框是空的。这是收到的错误之一:
System.Windows.Data Error: 40 : BindingExpression path error: 'Values' property not found on 'object' ''Sequence' (HashCode=31195541)'. BindingExpression:Path=Values; DataItem='Sequence' (HashCode=31195541); target element is 'ComboBox' (Name=ComboBox1'); target property is 'ItemsSource' (type 'IEnumerable')
将 DataGrid 绑定到更多集合的正确方法是什么?或者如何在 CellEdit 和 TextBox 上显示组合框?
您可以从错误消息中看出绑定失败,因为框架无法在 Sequence 类型的对象上找到 Values 和 Categories 属性。发生这种情况是因为您的 DataGrid 中的每一行都有底层序列作为其 DataContext。
如果您不想将 Values 和 Categories 集合添加到 Sequence 对象,那么您需要做的是更改您的 Bindings,以便它们绑定到父 DataContext,而不是行 DataContext。
试试这个例子,它将绑定重定向到 DataGrid 的 DataContext:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox x:Name="ComboBox2" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.Categories}"/>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>