[英]C# wpf binding in TabControl
我的应用程序有问题。 我使用 2 TabControl(主要和子)。 在我的子控件上,我有 2 个 TabItem。 一切正常,但 DataGridTextColumn.Header 绑定仅适用于第一个 TabItem。 显示窗口时(单击按钮后)将窗口 DataContext 设置为 ViewModelClass
第二个 TabItem 没有列名。 绑定错误是:
System.Windows.Data 错误:4:无法找到引用“RelativeSource FindAncestor, AncestorType='System.Windows.Controls.DataGrid', AncestorLevel='1''的绑定源。 BindingExpression:Path=DataContext.Translations.NumberText; 数据项=空; 目标元素是 'TextBlock' (Name=''); 目标属性是“文本”(类型“字符串”)
这是代码片段:
<TabControl x:Name="ovTcMain">
<TabItem Header="{Binding Translations.CodeBooksText }" TabIndex="0">
<Grid Style="{StaticResource MainGrid}">
<Grid.RowDefinitions>
<RowDefinition Height="6*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<TabControl x:Name="ovTcOptions" Grid.Row="0" SelectedIndex="{Binding Path=SelectedIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" >
<TabItem Header="{Binding Translations.ResortsText}" TabIndex="0" >
<DataGrid x:Name="ovTiCostCenters"
ItemsSource="{Binding CodeBooks[CostCenter], Mode=TwoWay}"
SelectedItem="{Binding SelectedCostCenter, Mode=TwoWay}"
ColumnWidth="*" AutoGenerateColumns="False" HorizontalAlignment="Stretch"
Visibility="Visible" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}" Width="auto">
<DataGridTextColumn.Header>
<TextBlock Text="{Binding DataContext.Translations.NumberText, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=DescriptionTerm}" Width="auto">
<DataGridTextColumn.Header>
<TextBlock Text="{Binding DataContext.Translations.TermText, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</TabItem>
<TabItem Header="{Binding Translations.BuildingsText}" TabIndex="1" >
<DataGrid x:Name="ovTiBuildings"
ItemsSource="{Binding CodeBooks[Building], Mode=TwoWay}"
SelectedItem="{Binding SelectedBuilding, Mode=TwoWay}"
ColumnWidth="*" AutoGenerateColumns="False" HorizontalAlignment="Stretch"
Visibility="Visible" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=Name}" Width="auto">
<DataGridTextColumn.Header>
<TextBlock Text="{Binding DataContext.Translations.NumberText, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Path=DescriptionTerm}" Width="auto">
<DataGridTextColumn.Header>
<TextBlock Text="{Binding DataContext.Translations.TermText, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</DataGridTextColumn.Header>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</TabItem>
你能帮我如何正确绑定 HeaderText 吗?
在 wpf 中,在具有项目的控件中,尤其是如果它们使用虚拟化时,有时 wpf 引擎不可靠并且找不到项目的祖先,(我认为是因为可能在将项目的绑定添加到VisualTree
之前对其进行评估) . 我在使用TabControls
(我认为在您的情况下有问题)、 DataGrids
、 ListBoxes
和ListViews
,甚至ComboBoxes
遇到过这种行为。 这是框架中的某种错误。 有时它只向您显示警告并且绑定仍然有效(就像您的第一个项目一样)。 重点是,有时RelativeSource
绑定是不可靠的。
此处描述了一种解决方法:
https://stackoverflow.com/a/15494510/891715
它适用于您提供的代码并正确绑定:
<UserConttrol.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</UserConttrol.Resources>
...
<TextBlock Text="{Binding Data.NumberText, Source={StaticResource proxy}}"/>
...
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy), new UIPropertyMetadata(null));
}
好的,答案是: RelativeSource
不可靠...
解决方案:
<UserControl.Resources>
<local:BindingProxy x:Key="proxy" Data="{Binding}" />
</UserControl.Resources>
<DataGridTemplateColumn Visibility="{Binding Data.IsVisible,
Source={StaticResource proxy},
Converter={StaticResource BooleanToVisibilityConverter}}">
public class BindingProxy : Freezable
{
protected override Freezable CreateInstanceCore()
{
return new BindingProxy();
}
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data.
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(object),
typeof(BindingProxy), new UIPropertyMetadata(null));
}
在这里找到了这个解决方案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.