绑定到 Materialdesign Flipper BackContent 和 ItemsControl DataTemplate 内部的视图模型时出现问题

Problem with binding to viewmodel inside of Materialdesign Flipper BackContent and ItemsControl DataTemplate

我在从 ItemsControl 的 DataTemplate 将文本绑定到 Viewmodels 属性 时遇到问题。我在鳍状肢内部有问题 BackContent 但在鳍状肢的 FrontContent 中我的绑定工作正常。我遇到问题的代码:

<TextBlock FontSize="22" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext.VMProperty}"/>

我的完整 xaml 是:

<Window x:Class="flipper.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:local="clr-namespace:flipper"
    xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Grid>
    <ItemsControl ItemsSource="{Binding Items}" RenderTransformOrigin="0.141,0.181">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <materialDesign:Flipper Style="{StaticResource MaterialDesignCardFlipper}" x:Name="FlipperCollection">
                    <materialDesign:Flipper.FrontContent>
                        <Border BorderThickness="0">
                            <Border.Background>
                                <LinearGradientBrush>
                                    <GradientStop Color="#09203F" Offset="1"/>
                                    <GradientStop Color="#3F4C6B" Offset="0"/>
                                </LinearGradientBrush>
                            </Border.Background>
                            <StackPanel Grid.Row="1"
                                        HorizontalAlignment="Center"
                                        VerticalAlignment="Center">
                                <TextBlock FontSize="22" Text="{Binding Name}" HorizontalAlignment="Center" Foreground="White"/>
                                <TextBlock FontSize="22" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext.VMProperty}"/>
                                <Button Style="{StaticResource MaterialDesignFlatButton}"
                                        Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext.cmdEditCompany}"
                                        Margin="0" Padding="0 0 5 0" VerticalAlignment="Center"
                                        HorizontalAlignment="Center"
                                        MinWidth="70"
                                        Foreground="#E5F0FF">
                                    <materialDesign:PackIcon Kind="Edit"
                                                             Width="20"
                                                             Height="20"/>
                                </Button>
                            </StackPanel>
                        </Border>
                    </materialDesign:Flipper.FrontContent>
                    <materialDesign:Flipper.BackContent>
                        <StackPanel Background="#E509203F">
                            <TextBlock FontSize="22" Text="{Binding TestData}" Foreground="White"/>
                            <TextBlock FontSize="22" Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}},Path=DataContext.VMProperty}"/>

                            <Button Style="{StaticResource MaterialDesignFlatButton}"
                                        Command="{x:Static materialDesign:Flipper.FlipCommand}"
                                        Margin="0" Padding="0 0 5 0" VerticalAlignment="Center"
                                        HorizontalAlignment="Center"
                                        MinWidth="70"
                                        Foreground="#E5F0FF">
                                    <materialDesign:PackIcon Kind="ArrowLeft"
                                                             Width="20"
                                                             Height="20"/>
                                </Button>
                            </StackPanel>
                    </materialDesign:Flipper.BackContent>
                </materialDesign:Flipper>
            </DataTemplate>
        </ItemsControl.ItemTemplate>

        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
</Grid>

模型和视图模型是:

class Data
{
    public string Name { get; set; }
    public string TestData { get; set; }
}
class MainViewModel:BindableBase
{

    private string _name;
    public string Name
    {
        get { return _name; }
        set { SetValue(ref _name, value); }
    }

    private string _TestData;
    public string TestData
    {
        get { return _TestData; }
        set { SetValue(ref _TestData, value); }
    }

    private List<Data> _Items;
    public List<Data> Items
    {
        get { return _Items; }
        set { SetValue(ref _Items, value); }
    }

    public DelegateCommand cmdEditCompany { get; set; }

    public MainViewModel()
    {
        onload();
        cmdEditCompany = new DelegateCommand(EditCompany);
    }

    private string _VMProperty;
    public string VMProperty
    {
        get { return _VMProperty; }
        set { SetValue(ref _VMProperty, value); }
    }


    private void EditCompany()
    {
        Flipper.FlipCommand.Execute(this, null);
    }


    private void onload()
    {
        Items = new List<Data>();
        Items.Add(new Data(){Name = "Name1",TestData = "TestData1"});
        Items.Add(new Data(){Name = "Name2",TestData = "TestData2"});
        Items.Add(new Data(){Name = "Name3",TestData = "TestData3"});
        Items.Add(new Data(){Name = "Name4",TestData = "TestData4"});
        Items.Add(new Data(){Name = "Name5",TestData = "TestData5"});
        VMProperty = "VM Test value";
    }


}

我该如何解决这个问题?

老问题,但我希望这对某人有所帮助。

这是因为 Flipper.BackContent 不属于 materialDesign:Flipper 的视觉树或逻辑树。 这个问题的解决方案是使用 Freezable class。 Freezable 对象可以继承 DataContext,即使它们不在可视化或逻辑树中。

public class BindingProxy : Freezable
{
    protected override Freezable CreateInstanceCore() => new BindingProxy();

    public object Data
    {
        get => GetValue(DataProperty);
        set => SetValue(DataProperty, value);
    }

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

添加到Window.Resources:

<Window.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</Window.Resources>

修复:

<TextBlock FontSize="22" Text="{Binding Data.VMProperty, Source={StaticResource proxy}}"/>

请注意,绑定路径的前缀是“Data”而不是“DataContext”,因为该路径现在是相对于 BindingProxy 对象的。