【问题标题】:MVVM binding not working in DataGrid column header when inside non-primary TabItem在非主 TabItem 内时,MVVM 绑定在 DataGrid 列标题中不起作用
【发布时间】:2019-12-24 21:13:04
【问题描述】:

我在辅助 TabItem 中有一个 DataGrid,我想将一些数据从视图模型绑定到标题。我能够将数据绑定到主 TabItem 中的 DataGrid 的标题,但相同的代码不适用于辅助 TabItem。我遵循了以下问题的答案,但它仍然无法正常工作,我不确定出了什么问题。我不确定我的数据上下文是否不正确,或者我的绑定设置是否正确。

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

这是我的代码:

XAML

<Window xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"  
        x:Class="TestWindow"
        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"
        mc:Ignorable="d"
        Title="Test Window" Height="645" Width="900">
    <StackPanel Orientation="Vertical">
        <TabControl>
            <TabItem Name="Primary_Tab" Header="Primary Tab">
                <!--Mock Data Grid-->
            </TabItem>
            <TabItem Name="Secondary_Tab" Header="Secondary Tab">
                <DataGrid Height="500" ItemsSource="{Binding GridDetails}" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False" CanUserAddRows="False">
                    <DataGrid.Resources>
                        <local:BindingProxy x:Key="proxy" Data="{Binding}" />
                    </DataGrid.Resources>
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="Name" Header="Name" Binding="{Binding Path='Name', Mode=OneTime}" IsReadOnly="True" Width="200" />
                        <DataGridTextColumn x:Name="ID" Header="ID" Binding="{Binding Path='ID', Mode=OneTime}" IsReadOnly="True" Width="100">
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn x:Name="NumClaims" Binding="{Binding Path='NumClaims', Mode=OneTime}" IsReadOnly="True" Width="100">
                            <DataGridTextColumn.Header>
                                <StackPanel>
                                    <TextBlock Text="Claims"/>
                                    <TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}, Path=DataContext}" Text="{Binding TotalClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}"/>
                                </StackPanel>
                            </DataGridTextColumn.Header>
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn x:Name="NewClaims" Binding="{Binding Path='NumNewClaims', Mode=OneTime}" IsReadOnly="True" Width="80">
                            <DataGridTextColumn.Header>
                                <StackPanel>
                                    <TextBlock Text="New Claims"/>
                                    <TextBlock DataContext="{Binding RelativeSource={RelativeSource AncestorType=DataGrid, Mode=FindAncestor}, Path=DataContext}" Text="{Binding TotalNewClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}"/>
                                </StackPanel>
                            </DataGridTextColumn.Header>
                            <DataGridTextColumn.CellStyle>
                                <Style TargetType="{x:Type DataGridCell}">
                                    <Setter Property="Background" Value="{Binding NumNewClaims}"/>
                                </Style>
                            </DataGridTextColumn.CellStyle>
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </TabItem>
        </TabControl>
    </StackPanel>
</Window>

查看模型

public class TestWindowViewModel : ViewModelBase
{
    private ObservableCollection<GridDetailModel> _gridDetails;
    public ObservableCollection<GridDetailModel> GridDetails
    {
        get
        {
            return _gridDetails;
        }
        set
        {
            SetProperty(ref _gridDetails, value);
        }
    }

    private string _totalClaims = "0";
    public string TotalClaims
    {
        get
        {
            return _totalClaims;
        }
        set
        {
            SetProperty(ref _totalClaims, value);
        }
    }

    private string _totalNewClaims = "0";
    public string TotalNewClaims
    {
        get
        {
            return _totalNewClaims;
        }
        set
        {
            SetProperty(ref _totalNewClaims, value);
        }
    }
}

绑定代理类

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

任何帮助将不胜感激。

【问题讨论】:

  • 如果是MVVM Light,需要在页面顶部放“DataContext="{Binding Source={StaticResource Locator}, Path=Main}”。(将Main替换为您用于虚拟机的类)
  • 我不确定如何实现定位器静态资源。你能提供一些我可以遵循的代码吗?
  • 在您使用 MVVM Light 时自动为您生成。

标签: c# wpf xaml mvvm datagrid


【解决方案1】:

我终于设法解决了绑定问题。似乎我有一堆干扰代理绑定的不必要的绑定上下文代码。对于将来遇到同样问题的任何人来说,这对我有用。请注意,我根本不需要更改视图模型或 BindingProxy 类。只需要在 XAML 部分做一些工作。

<Window xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"  
        x:Class="TestWindow"
        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"
        mxlns:local="clr-namespace:MyNamespace"
        mc:Ignorable="d"
        Title="Test Window" Height="645" Width="900">
    <StackPanel Orientation="Vertical">
        <TabControl>
            <TabItem Name="Primary_Tab" Header="Primary Tab">
                <!--Mock Data Grid-->
            </TabItem>
            <TabItem Name="Secondary_Tab" Header="Secondary Tab">
                <DataGrid Height="500" ItemsSource="{Binding GridDetails}" HorizontalAlignment="Left" VerticalAlignment="Top" AutoGenerateColumns="False" CanUserAddRows="False">
                    <DataGrid.Resources>
                        <local:BindingProxy x:Key="proxy" Data="{Binding}" />
                    </DataGrid.Resources>
                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="Name" Header="Name" Binding="{Binding Path='Name', Mode=OneTime}" IsReadOnly="True" Width="200" />
                        <DataGridTextColumn x:Name="ID" Header="ID" Binding="{Binding Path='ID', Mode=OneTime}" IsReadOnly="True" Width="100">
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn x:Name="NumClaims" Binding="{Binding Path='NumClaims', Mode=OneTime}" IsReadOnly="True" Width="100">
                            <DataGridTextColumn.Header>
                                <StackPanel>
                                    <TextBlock Text="Claims"/>
                                    <TextBlock Text="{Binding Path=Data.TotalClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}" />
                                </StackPanel>
                            </DataGridTextColumn.Header>
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                        <DataGridTextColumn x:Name="NewClaims" Binding="{Binding Path='NumNewClaims', Mode=OneTime}" IsReadOnly="True" Width="80">
                            <DataGridTextColumn.Header>
                                <StackPanel>
                                    <TextBlock Text="New Claims"/>
                                    <TextBlock Text="{Binding Path=Data.TotalNewClaims, UpdateSourceTrigger=PropertyChanged, Source={StaticResource proxy}}" />
                                </StackPanel>
                            </DataGridTextColumn.Header>
                            <DataGridTextColumn.CellStyle>
                                <Style TargetType="{x:Type DataGridCell}">
                                    <Setter Property="Background" Value="{Binding NumNewClaims}"/>
                                </Style>
                            </DataGridTextColumn.CellStyle>
                            <DataGridTextColumn.ElementStyle>
                                <Style TargetType="{x:Type TextBlock}">
                                    <Setter Property="HorizontalAlignment" Value="Center" />
                                </Style>
                            </DataGridTextColumn.ElementStyle>
                        </DataGridTextColumn>
                    </DataGrid.Columns>
                </DataGrid>
            </TabItem>
        </TabControl>
    </StackPanel>
</Window>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-22
    • 2023-03-07
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 2015-06-16
    • 2017-04-15
    相关资源
    最近更新 更多