繁体   English   中英

TabControl 中的 C# wpf 绑定

[英]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 (我认为在您的情况下有问题)、 DataGridsListBoxesListViews ,甚至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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM