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