Binding not working in DataGrid column header when inside non-primary TabItem

只愿长相守 提交于 2020-01-24 19:37:12

问题


I have a DataGrid which has a bound UI control in its header. The binding is to a a field in a view model. The grid is inside a TabControl. When the grid is on the initial tab in the tab control, all works well.

However, when the grid isn't on the initial tab, no binding seems to take place. There's no console output, value converters aren't being invoked, trace level logging isn't reporting anything.

Here's a trivial, reproducible example:

View Model

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

回答1:


After trying to fix your issue for a few minutes without success, i've found a solution online which seems to fix your issue.

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

I've tried it and it works! Good luck!

Heres the xaml code

<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>

And the Binding Proxy class :

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


来源:https://stackoverflow.com/questions/52461090/binding-not-working-in-datagrid-column-header-when-inside-non-primary-tabitem

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!