绑定DataGrid中的ComboBox标头

时间:2015-02-06 02:16:39

标签: c# wpf xaml mvvm datagrid

我在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看起来像这样(只是绑定所在的顶部):

<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它可以正常工作。但是当插入标题时它不会填充(我认为事件绑定也不起作用,但是不能验证,因为它没有填充,因此无法进行选择)。

2 个答案:

答案 0 :(得分:2)

您需要在绑定中使用RelativeSource。它最终会看起来像这样:

"{Binding DataContext.oTran, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"

答案 1 :(得分:1)

添加凯利建议。请参阅添加组合框列的完整代码。

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