绑定到 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 对象的。
我在从 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 对象的。