C# DataGrid中ComboBox头的绑定
我在WPF MVVM模式应用程序中有一个DataGrid,我正在尝试使用头中的一个组合框来过滤网格。当所有代码都在Window类(不是MVVM)中时,我可以这样做,但为了我自己,我尝试将其绑定到VM以获得相同的结果。以下是XAML:C# DataGrid中ComboBox头的绑定,c#,wpf,xaml,mvvm,datagrid,C#,Wpf,Xaml,Mvvm,Datagrid,我在WPF MVVM模式应用程序中有一个DataGrid,我正在尝试使用头中的一个组合框来过滤网格。当所有代码都在Window类(不是MVVM)中时,我可以这样做,但为了我自己,我尝试将其绑定到VM以获得相同的结果。以下是XAML: <DataGridTextColumn x:Name="transNameColumn" Binding="{Binding TransName}" Width="325"> <DataGridTextColumn.Header> &
<DataGridTextColumn x:Name="transNameColumn" Binding="{Binding TransName}" Width="325">
<DataGridTextColumn.Header>
<ComboBox ItemsSource="{Binding oTran}" DisplayMemberPath="TransName" SelectedValuePath="UID"
HorizontalAlignment="Left" Width="315">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding Transmittal_ComboSelect}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</DataGridTextColumn.Header>
它所在的DataGrid如下所示(仅在绑定所在的顶部):
顶层网格被绑定为:
<Grid DataContext="{Binding}">
我在想,因为组合框在数据网格中,所以绑定会出错。当我拥有自己的组合框时,使用相同的XAML它工作得很好。但是当作为标题插入时,它不会填充(我认为事件绑定也不会工作,但无法验证,因为它不会填充,所以无法进行选择)。您需要在绑定中使用RelativeSource。它最终会看起来像这样:
"{Binding DataContext.oTran, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
补充凯利的建议。请参阅添加组合框列的完整代码
<Grid>
<DataGrid AutoGenerateColumns="False" Name="dgr" ItemsSource="{Binding GridItems}" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" >
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="combo" Grid.Row="0"/>
<ComboBox Grid.Row="1" Width="70" HorizontalAlignment="Center" Name="cboBhp"
ItemsSource="{Binding Path=DataContext.ComboItems,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
SelectedValue="{Binding Path=DataContext.ComboValue, RelativeSource={RelativeSource AncestorType={x:Type Window}},
Mode=TwoWay}">
</ComboBox>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public class GridSample
{
public string Name { get; set; }
}
public class MainViewModel:INotifyPropertyChanged
{
private string comboValue;
public string ComboValue
{
get { return comboValue; }
set
{
if (comboValue != value)
{
comboValue = value;
NotifyPropertyChanged("ComboValue");
}
}
}
public MainViewModel()
{
ComboItems = new ObservableCollection<string>();
ComboItems.Add("pascal");
ComboItems.Add("Braye");
ComboValue = "pascal";
GridItems = new ObservableCollection<GridSample>() {
new GridSample() { Name = "Jim"} ,new GridSample() { Name = "Adam"} };
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string str)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(str));
}
}
public ObservableCollection<GridSample> GridItems { get; set; }
public ObservableCollection<string> ComboItems { get; set; }
}
公共部分类Window1:Window
{
公共窗口1()
{
初始化组件();
this.DataContext=新的MainViewModel();
}
}
公共类网格示例
{
公共字符串名称{get;set;}
}
公共类MainViewModel:INotifyPropertyChanged
{
私有字符串值;
公共字符串组合值
{
获取{return comboValue;}
设置
{
如果(组合值!=值)
{
组合值=值;
NotifyPropertyChanged(“ComboValue”);
}
}
}
公共主视图模型()
{
ComboItems=新的ObservableCollection();
组合项。添加(“pascal”);
组合项目。添加(“Braye”);
ComboValue=“pascal”;
GridItems=新的ObservableCollection(){
new GridSample(){Name=“Jim”},new GridSample(){Name=“Adam”};
}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串str)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(str));
}
}
公共ObservableCollection GridItems{get;set;}
公共ObservableCollection组合项{get;set;}
}
谢谢,我会把它加回去的。我认为在前面的步骤中,我已经删除了这一行(当从非MVVM移植到MVVM版本时)。我正慢慢开始理解DataContext在做什么。感谢代码中的出色细节。即使我最终把一切都安排好了,看到其他的方法和风格总是很好的。当我看到另一个例子建立起来时,我的思维中很少没有看到另一个错误。
<Grid>
<DataGrid AutoGenerateColumns="False" Name="dgr" ItemsSource="{Binding GridItems}" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}" >
<DataGridTextColumn.Header>
<StackPanel Orientation="Horizontal">
<TextBlock Text="combo" Grid.Row="0"/>
<ComboBox Grid.Row="1" Width="70" HorizontalAlignment="Center" Name="cboBhp"
ItemsSource="{Binding Path=DataContext.ComboItems,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
SelectedValue="{Binding Path=DataContext.ComboValue, RelativeSource={RelativeSource AncestorType={x:Type Window}},
Mode=TwoWay}">
</ComboBox>
</StackPanel>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
this.DataContext = new MainViewModel();
}
}
public class GridSample
{
public string Name { get; set; }
}
public class MainViewModel:INotifyPropertyChanged
{
private string comboValue;
public string ComboValue
{
get { return comboValue; }
set
{
if (comboValue != value)
{
comboValue = value;
NotifyPropertyChanged("ComboValue");
}
}
}
public MainViewModel()
{
ComboItems = new ObservableCollection<string>();
ComboItems.Add("pascal");
ComboItems.Add("Braye");
ComboValue = "pascal";
GridItems = new ObservableCollection<GridSample>() {
new GridSample() { Name = "Jim"} ,new GridSample() { Name = "Adam"} };
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string str)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(str));
}
}
public ObservableCollection<GridSample> GridItems { get; set; }
public ObservableCollection<string> ComboItems { get; set; }
}