绑定 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; }
}