title author date CreateTime categories
win10 uwp 在 ItemsPanelTemplate 里面通过样式绑定 Orientation 显示方向
lindexi
2019-03-16 10:28:44 +0800
2019-03-16 09:55:10 +0800
Win10 UWP

在 UWP 是不支持在 Setter 里面的 Value 进行绑定,如果想要在 ItemsPanelTemplate 里面绑定显示方向,那么需要通过附加属性的方法绑定。如果在后台代码定义了 Orientation 属性想要在 xaml 绑定到 ListView 的样式,可以尝试多创建一个帮助属性,用于在里面绑定

我在后台代码定义了属性 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); }
}

我在 xaml 有一个 ListView 准备将 Orientation 绑定到 ListView 的 ItemsPanel 通过一个样式

<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="{Binding Orientation, RelativeSource={RelativeSource Mode=TemplatedParent}}"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>

在开始绑定的时候,没有提示任何信息,也没有绑定成功

因为在 Setter Class (Windows.UI.Xaml) - Windows UWP applications 说到在 UWP 是不支持在 Setting 的 Value 绑定,这个和 WPF 不相同,建议使用静态的资源

Windows Presentation Foundation (WPF) and Microsoft Silverlight supported the ability to use a Binding expression to supply the Value for a Setter in a Style. The Windows Runtime doesn't support a Binding usage for Setter.Value (the Binding won't evaluate and the Setter has no effect, you won't get errors, but you won't get the desired result either). When you convert XAML styles from Windows Presentation Foundation (WPF) or Microsoft Silverlight XAML, replace any Binding expression usages with strings or objects that set values, or refactor the values as shared {StaticResource} markup extension values rather than Binding -obtained values.

在这里是几乎无法通过静态资源做到绑定的,那么如何让在后台代码修改的时候,可以修改 xaml 里面的 ListView 的列表显示方向绑定到后台的属性?

在后台代码创建一个帮助绑定的类,这个类里面包含了一个附加属性,将会在这个附加属性里面尝试绑定

    public class BindingHelper
{
public static readonly DependencyProperty ItemsPanelOrientationProperty = DependencyProperty.RegisterAttached(
"ItemsPanelOrientation", typeof(bool), typeof(BindingHelper),
new PropertyMetadata(default(bool), ItemsPanelOrientation_OnPropertyChanged)); }

核心就在 ItemsPanelOrientation_OnPropertyChanged 方法,在这个方法里面找到 ItemsStackPanel 然后设置绑定

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

那么为什么需要在 listView.Dispatcher.RunAsync 里面绑定?因为初始的时候 listView.ItemsPanelRoot 是没有值的,需要等待创建完成这个属性

上面的代码是直接绑定,绑定到 DataContext 也就是需要在 ListView 指定 DataContext 才可以绑定

指定当前的 Page 作为 ListView 的 DataContext 请看代码

<Page x:Name="Page1">
<ListView DataContext="{x:Bind Page1}">

在样式里面多设置一个附加属性,这里的 Orientation 绑定是不会绑定的

                <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 进行测试

<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 />
</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>

在后台代码的构造函数写一个循环,定时修改后台属性的方向的大小请看代码

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

现在看起来的界面是

写到这里的代码请看 https://github.com/lindexi/lindexi_gd/tree/43ee46e847179b61157c5bfbbdec0382ccc97268/KeejemairbouLirallpurpallnasfakaw

不过附加属性里面使用延迟还是不靠谱,可能延迟拿到的 ListView 的数据是空,所以建议的方法是修改附加属性

    public class BindingHelper
{
public static readonly DependencyProperty ItemsPanelOrientationProperty = DependencyProperty.RegisterAttached(
"ItemsPanelOrientation", typeof(bool), typeof(BindingHelper),
new PropertyMetadata(default(bool), ItemsPanelOrientation_OnPropertyChanged)); private static void ItemsPanelOrientation_OnPropertyChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
if (d is ListView listView)
{
if (listView.IsLoaded)
{
SetBind(listView);
}
else
{
listView.Loaded += ListView_Loaded;
}
}
} private static void ListView_Loaded(object sender, RoutedEventArgs e)
{
SetBind((ListView) sender);
} private static void SetBind(ListView listView)
{
if (listView.ItemsPanelRoot is ItemsStackPanel stackPanel)
{
BindingOperations.SetBinding(stackPanel, ItemsStackPanel.OrientationProperty, new Binding()
{
Path = new PropertyPath("Orientation"),
Mode = BindingMode.OneWay
});
}
} public static void SetItemsPanelOrientation(DependencyObject element, bool value)
{
element.SetValue(ItemsPanelOrientationProperty, value);
} public static bool GetItemsPanelOrientation(DependencyObject element)
{
return (bool) element.GetValue(ItemsPanelOrientationProperty);
}
}

2019-3-16-win10-uwp-在-ItemsPanelTemplate-里面通过样式绑定-Orientation-显示方向的更多相关文章

  1. win10 uwp 商业游戏 1.1.5

    本文是在win10 uwp 商业游戏 基础上继续开发,添加一些无聊的游戏 因为在发布几个月,下载量很少,小伙伴说游戏就玩不到几分钟就不想玩,于是我就想加入其他游戏 下面我来告诉大家如何在游戏中添加多个 ...

  2. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  3. Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

    安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneG ...

  4. Win10 UWP开发系列:实现Master/Detail布局

    在开发XX新闻的过程中,UI部分使用了Master/Detail(大纲/细节)布局样式.Win10系统中的邮件App就是这种样式,左侧一个列表,右侧是详情页面.关于这种 样式的说明可参看MSDN文档: ...

  5. Win10 UWP开发实现Bing翻译

    微软在WP上的发展从原来的Win7到Win8,Win8.1,到现在的Win10 UWP,什么是UWP,UWP即Windows 10 中的Universal Windows Platform简称.即Wi ...

  6. Win10/UWP开发—使用Cortana语音与App后台Service交互

    上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比 ...

  7. 【Win10 UWP】后台任务与动态磁贴

    动态磁贴(Live Tile)是WP系统的大亮点之一,一直以来受到广大用户的喜爱.这一讲主要研究如何在UWP应用里通过后台任务添加和使用动态磁贴功能. 从WP7到Win8,再到Win10 UWP,磁贴 ...

  8. 【Win10 UWP】URI Scheme(一):Windows Store协议的解析和使用

    协议是Windows Phone和Windows Store应用的一个重要特点,可以做到在不同应用之间进行互相呼起调用.小小协议,学问大着呢.我打算写几篇关于协议在UWP中使用的文章. 这一讲的主要对 ...

  9. 【Win10 UWP】QQ SDK(二):SDK的回调处理

    上一讲,我们介绍了QQ SDK的使用方法,请看<[Win10 UWP]QQ SDK(一):SDK基本使用方法> 一. 回调的基本形式 从前面的介绍中我们知道,我们的应用和QQ客户端之间需要 ...

  10. Win10 UWP应用发布流程

    简介 Win10 UWP应用作为和Win8.1 UAP应用不同的一种新应用形式,其上传至Windows应用商店的流程也有了一些改变. 这篇博文记录了我们发布一款Win10 UWP应用的基本流程,希望为 ...

随机推荐

  1. Nginx 配置参数

    1 Proxy_send_timeout 定义后端在多久的时间内必须返回完所有的数据给Nginx. 2 Proxy_read_timeout

  2. normal use for autotools

    1. remove temporary files, only used for test purpose. ls | sed -e rm -rf 2. edit autogen.sh echo &q ...

  3. MySql 主从复制及深入了解

    分享一个不错的mysql文章 https://segmentfault.com/a/1190000008942618

  4. ASP.Net 第一天笔记 MVC 控制器与视图数据传递注意事项

    1.如果方法的参数的名称与表单元素Name属性的值一致的话,会自动填充 2.如果表单元素的Name属性与实体类型中属性一致,那么表单中的数据会自动赋值给实体中的属性 3.控制器中重载的方法 方法前上边 ...

  5. python调用tushare获取A股上市公司基础信息

    接口:stock_company 描述:获取上市公司基础信息 积分:用户需要至少120积分才可以调取,具体请参阅最下方积分获取办法 注:tushare库下载和初始化教程,请查阅我之前的文章 输入参数 ...

  6. 移动端新建html页面

    这是一些头部设置 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...

  7. 49-Ubuntu-其他命令-1-文件软链接

    序号 命令 作用 01 ln -s 被链接的原文件 链接文件 建立文件的软链接,用通俗的方式讲类似于Windows下的快捷方式 注意: 没有-s选项建立的是一个硬链接文件--->>两个文件 ...

  8. Operator '?:' has lower precedence than '*'; '*' will be evaluated first

    1.项目中用宏的时候,遇到如下警告 Operator '?:' has lower precedence than '*'; '*' will be evaluated first 2.错误原因 *操 ...

  9. centos7 sshd 安全设置

    ssh 的安全机制 1.SSH之所以能够保证安全,原因在于它采用了非对称加密技术(RSA)加密了所有传输的数据.   2.传统的网络服务程序,如FTP等在网络上用明文传送数据.用户帐号和用户口令,很容 ...

  10. Replication Controller、Replica Set

    假如我们现在有一个Pod正在提供线上的服务,我们来想想一下我们可能会遇到的一些场景: 某次运营活动非常成功,网站访问量突然暴增 运行当前Pod的节点发生故障了,Pod不能正常提供服务了 第一种情况,可 ...