【问题标题】:Binding not working in DataGrid column header when inside non-primary TabItem在非主 TabItem 内时,绑定在 DataGrid 列标题中不起作用
【发布时间】:2018-09-23 06:03:41
【问题描述】:

我有一个DataGrid,它的标题中有一个绑定的 UI 控件。绑定到视图模型中的字段。网格位于TabControl 内。当网格位于选项卡控件的初始选项卡上时,一切正常。

但是,当网格不在初始选项卡上时,似乎没有发生绑定。没有控制台输出,没有调用值转换器,没有报告任何跟踪级别的日志。

这是一个简单的、可重现的例子:

查看模型

public class ViewModel : INotifyPropertyChanged
{
    private string _camel = "Bertie";

    public string Camel
    {
        get => _camel;
        set
        {
            if (value == _camel) return;
            _camel = value;
            OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

MainWindow.xaml

<Window x:Class="ThingsWithHumps.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:thingsWithHumps="clr-namespace:ThingsWithHumps"
        mc:Ignorable="d"
        Height="350" Width="350">
    <Window.DataContext>
        <thingsWithHumps:ViewModel/>
    </Window.DataContext>
    <TabControl>
        <!-- This TabItem prevents the TextBlock being bound -->
        <TabItem Header="Troublesome tab"/>
        <TabItem Header="Humps">
            <DataGrid AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTemplateColumn>
                        <DataGridTemplateColumn.Header>

                            <!-- Troublesome binding -->
                            <TextBlock Text="{Binding Path=DataContext.Camel,
                                   UpdateSourceTrigger=PropertyChanged,
                                   RelativeSource={RelativeSource FindAncestor,
                                       AncestorType={x:Type Window}}}" />
                        </DataGridTemplateColumn.Header>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </TabItem>
    </TabControl>
</Window>

MainWindow.xaml.cs

namespace ThingsWithHumps
{
    public partial class MainWindow 
    {
        public MainWindow() => InitializeComponent();
    }
}

【问题讨论】:

  • 在这个例子中你的虚拟机没有实现INotifyPropertyChanged
  • 谢谢迈克尔;刚刚更新了代码和问题,但同样的问题仍然存在。

标签: wpf xaml wpfdatagrid tabcontrol


【解决方案1】:

在尝试解决您的问题几分钟但没有成功后,我在网上找到了一个似乎可以解决您的问题的解决方案。

http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

我试过了,效果很好!祝你好运!

这是 xaml 代码

<TabControl>
    <!-- This TabItem prevents the TextBlock being bound -->
    <TabItem Header="Troublesome tab"/>
    <TabItem Header="Humps">
        <DataGrid AutoGenerateColumns="False">
            <DataGrid.Resources>
                <local:BindingProxy x:Key="proxy" Data="{Binding}" />
            </DataGrid.Resources>
            <DataGrid.Columns>
                <DataGridTemplateColumn>

                    <DataGridTemplateColumn.Header>

                        <!-- Troublesome binding -->
                        <TextBlock Text="{Binding Path=Data.Camel,
                               UpdateSourceTrigger=PropertyChanged,
                               Source={StaticResource proxy}}" />
                    </DataGridTemplateColumn.Header>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </TabItem>
</TabControl>

还有绑定代理类:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

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

【讨论】:

  • 天哪,这并不明显!有趣的是我什至没有看到任何控制台输出。非常感谢,亚历山德拉;可以确认该方法有效。
  • (抱歉,Alexandre,不是 Alexandra!)
  • 好问题,好答案!它结束了我几个小时的长途旅行。但是:这里的第二个标签有什么问题?
猜你喜欢
  • 2019-12-24
  • 2016-06-22
  • 2023-03-07
  • 1970-01-01
  • 2015-06-16
  • 2017-04-15
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多