绑定 DataGrid 中的 ComboBox Header
Binding for ComboBox Header in DataGrid
我在 WPF MVVM 模式应用程序中有一个 DataGrid,我正在尝试使用 header 中的组合框来过滤网格。当所有代码都在 Window class(不是 MVVM)中时,我可以这样做,但为了我自己,我试图将它绑定到 VM 以获得相同的结果。这是 XAML:
<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 看起来像这样(就是绑定所在的顶部):
<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>
顶层网格绑定如下:
<Grid DataContext="{Binding}">
我在想,因为组合框在数据网格内,所以绑定被弄乱了。当我有自己的组合框时,使用相同的 XAML 它工作正常。但是当作为 header 插入时它不会填充(我认为事件绑定也不起作用,但无法验证因为它没有填充所以没有办法进行选择)。
您需要在绑定中使用 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; }
}
我在 WPF MVVM 模式应用程序中有一个 DataGrid,我正在尝试使用 header 中的组合框来过滤网格。当所有代码都在 Window class(不是 MVVM)中时,我可以这样做,但为了我自己,我试图将它绑定到 VM 以获得相同的结果。这是 XAML:
<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 看起来像这样(就是绑定所在的顶部):
<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>
顶层网格绑定如下:
<Grid DataContext="{Binding}">
我在想,因为组合框在数据网格内,所以绑定被弄乱了。当我有自己的组合框时,使用相同的 XAML 它工作正常。但是当作为 header 插入时它不会填充(我认为事件绑定也不起作用,但无法验证因为它没有填充所以没有办法进行选择)。
您需要在绑定中使用 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; }
}