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. 文本表征:SoW、BoW、TF-IDF、Hash Trick、doc2vec、DBoW、DM

    原文地址:https://www.jianshu.com/p/2f2d5d5e03f8 一.文本特征 (一)基本文本特征提取 词语数量 常,负面情绪评论含有的词语数量比正面情绪评论更多. 字符数量 常 ...

  2. 用python+tushare获取股票前复权后复权行情数据

    接口名称 :pro_bar 接口说明 :复权行情通过通用行情接口实现,利用Tushare Pro提供的复权因子进行计算,目前暂时只在SDK中提供支持,http方式无法调取. Python SDK版本要 ...

  3. git常用操作笔记

    这是我看了廖雪峰的git教程,写的笔记,仅作为一个学习的记录 一.大多数我们面临的是已经有一个进行中的项目了,我们只需克隆下来就可以了 1.安装git,安装完后,可输入git,回车,查看是否已安装 2 ...

  4. Java的GC是什么?做了什么?

    Java GC是Java的垃圾回收机制 Java堆是被所有线程共享的一块内存区域,所有对象实例和数组都在堆上进行内存分配.为了高效的进行垃圾回收,虚拟机把堆内存分为新生代,老年代和永久代3个区域 新生 ...

  5. 什么是URI、URL、URN、URC和Data URI?

    前言 不知道大家有没有电话拨号通过'猫'上网的经历,那时测试网络是否连接,最好的方式就是打开浏览器输入: www.baidu.com 那会管这一连串字母叫' 网址 '.之后上大学(计算机专业),知道了 ...

  6. docker Dockerfile学习---构建apache环境

    1.创建目录,上传包 创建项目目录 $ mkdir apache_php $ cd apache_php 把包下载后放到服务器该目录下 $ ls apr-....tar.gz 2.创建Dockerfi ...

  7. CSS3(@media)判断手机横竖屏

    @media all and (orientation : landscape) { h2{color:red;}/*横屏时字体红色*/ } @media all and (orientation : ...

  8. webpack4.0高级

    环境变量 webpack --env.NODE_ENV=local --env.production --progress Tree Shaking 移除JS上下文字未被引用的代码 只支持ES6的im ...

  9. scala中函数简单使用记录

    object funcHighLevel { def main(args: Array[String]): Unit = { // 创建一个匿名函数 val sayFunc = (name: Stri ...

  10. Apache 环境变量配置

    在path 中加入  C:\__S_D_K__\AndroidApache\apache-ant-1.9.14\bin 我的路径在C盘