C# DataGrid中ComboBox头的绑定

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> &

我在WPF MVVM模式应用程序中有一个DataGrid,我正在尝试使用头中的一个组合框来过滤网格。当所有代码都在Window类(不是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如下所示(仅在绑定所在的顶部):


顶层网格被绑定为:

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