我想创建一个模板化控件,它源自ItemsControl
,并且如果需要可以改变它的方向。
所以,我试过这个:
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="{Binding Orientation, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
它没用,然后我尝试用Mode = Self
,没有成功。
Orientation
是一个DependencyProperty
,我已在.cs文件中声明。
我遇到过wpf的旧解决方案,它使用AncestorType
- 在UWP中不可用。
我怎么解决这个问题?
谢谢。
这不是UWP的支持。见:Setter Class (Windows.UI.Xaml) - Windows UWP applications | Microsoft Docs
Windows Presentation Foundation(WPF)和Microsoft Silverlight支持使用Binding表达式为样式中的Setter提供值的功能。 Windows运行时不支持Setter.Value的绑定用法(Binding不会评估,Setter不起作用,你不会得到错误,但你也不会得到所需的结果)。从Windows Presentation Foundation(WPF)或Microsoft Silverlight XAML转换XAML样式时,将任何Binding表达式用法替换为设置值的字符串或对象,或将值重构为共享{StaticResource}标记扩展值而不是Binding -obtained值。
但您可以使用attache属性来执行此操作。
在MainPage中添加Orientation属性。
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(MainPage), new PropertyMetadata(default(Orientation)));
public Orientation Orientation
{
get { return (Orientation) GetValue(OrientationProperty); }
set { SetValue(OrientationProperty, value); }
}
添加BindingHelper并定义attache属性。
public static readonly DependencyProperty ItemsPanelOrientationProperty = DependencyProperty.RegisterAttached(
"ItemsPanelOrientation", typeof(bool), typeof(BindingHelper),
new PropertyMetadata(default(bool), ItemsPanelOrientation_OnPropertyChanged));
在ItemsPanelOrientation_OnPropertyChanged
中设置绑定到ItemsStackPanel.Orientation。
private static async void ItemsPanelOrientation_OnPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if (d is ListView listView)
{
await listView.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
if (listView.ItemsPanelRoot is ItemsStackPanel stackPanel)
{
BindingOperations.SetBinding(stackPanel, ItemsStackPanel.OrientationProperty, new Binding()
{
Path = new PropertyPath("Orientation"),
Mode = BindingMode.OneWay
});
}
});
}
}
在xaml中,编写BindingHelper.ItemsPanelOrientation和ItemsPanelTemplate。
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="{Binding Orientation, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="local:BindingHelper.ItemsPanelOrientation" Value="True"></Setter>
</Style>
</ListView.Style>
你应该在ListView中设置DataContext。 DataContext是名为Page1
的页面。
<Page
x:Class="KeejemairbouLirallpurpallnasfakaw.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:KeejemairbouLirallpurpallnasfakaw"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="Page1"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<ListView DataContext="{x:Bind Page1}">
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="{Binding Orientation, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="local:BindingHelper.ItemsPanelOrientation" Value="True"></Setter>
</Style>
</ListView.Style>
<ListView.Items>
<TextBlock Text="1"></TextBlock>
<TextBlock Text="2"></TextBlock>
<TextBlock Text="3"></TextBlock>
</ListView.Items>
</ListView>
</Grid>
</Page>
在MainPage中编写代码以更改方向。
public MainPage()
{
this.InitializeComponent();
Task.Run(async () =>
{
while (true)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() => { Orientation = Orientation.Horizontal; });
await Task.Delay(TimeSpan.FromSeconds(5));
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
() => { Orientation = Orientation.Vertical; });
await Task.Delay(TimeSpan.FromSeconds(5));
}
});
}
github中的所有代码:https://github.com/lindexi/lindexi_gd/tree/43ee46e847179b61157c5bfbbdec0382ccc97268/KeejemairbouLirallpurpallnasfakaw