我正在使用WPF组合框来过滤项目,但我决定将其放入我的数据网格中,但是我可能无法使其工作,因为只有在数据网格之外时,我才能使其工作.
我认为问题是因为
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, or ElementName=win
在datagrid中不受支持,因此如何使它工作.
这是我得到的错误
System.Windows.Data Error: 4 : Cannot find source for binding with reference ‘RelativeSource FindAncestor, AncestorType=’System.Windows.Window’, AncestorLevel=’1”. BindingExpression:Path=SelectedParam; DataItem=null; target element is ‘ComboBox’ (Name=’Krydsmålbox’); target property is ‘SelectedValue’ (type ‘Object’)
<DataGrid x:Name="hjuldata"
ItemsSource="{Binding Source={StaticResource cvsTasks}}"
CanUserAddRows="False" BorderBrush="#FF303030" Foreground="#FF00FB0B" Background="#FF303030" AutoGenerateColumns="False" GridLinesVisibility="None" VerticalAlignment="Center" Height="644" Canvas.Left="20" Canvas.Top="257" Width="1250" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Krydsmålet}">
<DataGridTextColumn.HeaderTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</DataTemplate>
</DataGridTextColumn.HeaderTemplate>
<DataGridTextColumn.Header>
<ComboBox x:Name="Krydsmålbox" Foreground="#FFEAEAEA" Background="#FF303030" FontSize="12"
Style="{StaticResource ComboBoxTest2}" ItemTemplate="{StaticResource cmbTemplate2}"
ItemsSource="{Binding}" SelectedValuePath="Krydsmålene"
SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}" BorderBrush="#FF303030" Height="40" DockPanel.Dock="Top" IsSynchronizedWithCurrentItem="True" SelectionChanged="Krydsmålbox_SelectionChanged" Canvas.Left="813" Canvas.Top="96" Width="146"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
数据模板
<DataTemplate x:Key="cmbTemplate2">
<WrapPanel Margin="0 5 0 5" Height="30">
<Image Width="10" Height="20" Stretch="Fill" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,15,0"/>
<Label Content="{Binding Krydsmålene}" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="16" Foreground="#FF00FB0B"/>
</WrapPanel>
</DataTemplate>
CS
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string SelectedParam
{
get { return _selectedParam; }
set
{
_selectedParam = value; OnPropertyChanged("SelectedParam");
if (_selectedParam == "Krydsmål") { BindData(); } else { hjuldata.ItemsSource = FilterKategori().Tables[0].DefaultView; ; }
}
}
public DataSet DTbindkryds()
{
Data = @"SELECT Krydsmålene FROM Data.Krydsmål";
//SQL statement to fetch entries from Krydsmål
DataSet dsdata = new DataSet();
//Open SQL Connection
using (conn = new SqlConnection(connStrings))
{
conn.Open();
//Initialize command object
using (conn = new SqlConnection(connStrings))
using (cmd = new SqlCommand(Data, conn))
{
SqlDataAdapter adapters = new SqlDataAdapter(cmd);
//Fill the result set
adapters.Fill(dsdata);
conn.Close();
}
}
return dsdata;
}
private void bindkrydsmål()
{
Krydsmålbox.ItemsSource = DTbindkryds().Tables[0].DefaultView;
}
解决方法:
我认为您的真正问题很小,而且WPF开发人员经常遇到.更改您的SelectedValue绑定,如下所示:
SelectedValue = "{Binding DataContext.SelectedParam, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}},UpdateSourceTrigger=PropertyChanged}"
由于您没有提供代码,因此无法为窗口分配DataContext,因此这是一个可行的选择.如果是相同的窗口类,则绑定应在没有DataContext的情况下进行.但是数据网格内部不支持RelativeSource绑定的假设是错误的.只要元素在控件的VisualTree中并且您的组合框在窗口的Visualtree中,RelativeSource都将起作用.对?
为了节省时间来证明这一事实,下面是演示(通过最大程度地重复使用代码并使用DataGrid标头中的模板创建).
XAML:
<DataGrid ItemsSource="{Binding Items}" CanUserAddRows="False" AutoGenerateColumns="False" VerticalAlignment="Stretch" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding DeviceState}">
<DataGridTextColumn.Header>
<ComboBox HorizontalAlignment="Stretch" Width="200" SelectedValuePath="DeviceState"
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window},Path=DataContext.Items}"
SelectedValue = "{Binding SelectedParam, RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type Window}}}" >
<ComboBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding DeviceState}" VerticalAlignment="Center" HorizontalAlignment="Stretch"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="200"/>
</DataGrid.Columns>
</DataGrid>
背后的代码:
public MainWindow()
{
Items = new List<Device>();
Items.Add(new Device() { Name = "Device1",DeviceState = 1 });
Items.Add(new Device() { Name = "Device2", DeviceState = 2 });
Items.Add(new Device() { Name = "Device3", DeviceState = 3 });
Items.Add(new Device() { Name = "Device4", DeviceState = 4 });
Items.Add(new Device() { Name = "Device5", DeviceState = 5 });
InitializeComponent();
}
public List<Device> Items { get; set; }
private string _selectedParam = "1";
public string SelectedParam
{
get { return _selectedParam; }
set
{
_selectedParam = value;
UpdateProperty("SelectedParam");
}
}
输出:
正如您在输出中看到的那样,默认情况下,datagrid头中的组合框具有一个选中项,如上XAML所示,这是使用相对源绑定反映出来的.