ItemsControl的UWP绑定方向

问题描述 投票:0回答:1

我想创建一个模板化控件,它源自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
1个回答
1
投票

这不是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

© www.soinside.com 2019 - 2024. All rights reserved.