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. 注解@Override

    Android的开发者对@Override肯定是非常熟悉,不管是自己的代码中还是书上都会出现,但是他是什么意思呢?如下: @Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处: ...

  2. OpenFileDialog 打开图片存储到电脑本地上

    替换图片 private void btnSkin_Click(object sender, RoutedEventArgs e) { string fName; OpenFileDialog ofd ...

  3. pta作业1

    7-1 打印沙漏 (20 分) 本题要求你写个程序把给定的符号打印成沙漏的形状.例如给定17个“*”,要求按下列格式打印 ***** *** * *** ***** 所谓“沙漏形状”,是指每行输出奇数 ...

  4. JQuery日记6.7 Javascript异步模型(二)

    异步模型看起来非常美,但事实上它也是有天生缺陷的.看以下代码 try { setTimeout( function(){ throw new Error( '你抓不到我的!' ); }, 100); ...

  5. man bash

    BASH(1) General Commands Manual BASH(1) NAME bash - GNU Bourne-Again SHell SYNOPSIS bash [options] [ ...

  6. 软工-五月心得体会 PB16110698

    伴随着愈发红润的骄阳,火热而紧张刺激的五月悄然而至.这一个月以来,曾经让同学们“废寝忘食”的软工课大作业终于告一段落,每周一篇的读书笔记也缓到半月一篇,着实令人长吐一口气.但这一份表面的余裕当然没有看 ...

  7. 网络编程之 OSI七层协议

    内容目录: 1.软件开发架构 2.OSI七层协议 3.每层协议介绍 1.软件开发架构 c/s架构: c:客户端 s:服务端 b/s架构: b:浏览器 s:服务器 本质:b/s其实也是c/s 2.OSI ...

  8. ajax-jq

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. redis主从和集群搭建

    主从搭建 redis的主从搭建非常简单,打开配置文件6379.conf,只需要将主节点的protected-mode设置为no,然后在从节点配置中加入:slaveof <masterip> ...

  10. 关于sublime使用中写less代码高亮显示问题

    一开始在没有配置的情况下在sublime中写less代码是不会有高亮显示的.下面说一下配置过程 一.安装Less2Css模块 打开sublime,ctrl+shift+p,输入package cont ...