XAML中DataTemplate变量隐藏的解决方法

这篇具有很好参考价值的文章主要介绍了XAML中DataTemplate变量隐藏的解决方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

title: XAML中DataTemplate变量隐藏的解决方法
date: 2023-11-13
categories: 编程
tags:
- C#
- .NET
- XAML

前言

微软的许多XAML框架,如WPF、UWP、WinUI3等,在DataTemplate下都会遇到变量隐藏(Variable shadowing)的问题。为了访问外部实例成员,经常需要写很多曲折的代码,但也没有办法。本文也无法解决这个问题,但记录了我知道的方法,以便在各种情况使用,争取将可读性的影响降到最低。

问题再现

按照需求创建了一个Page

public sealed partial class SamplePage : Page
{
    public string OuterMember { get; set; } = "OuterMember";

    public SamplePage()
    {
        ViewModels = new ViewModel[] { new("a"), new("b"), new("c"), };
        InitializeComponent();
    }

    public ViewModel[] ViewModels { get; }
}

public class ViewModel(string text)
{
    public string Text { get; set; } = text;
}
<Page
    x:Class="SampleApp.SamplePage"
    ...>
    <ItemsRepeater ItemsSource="{x:Bind ViewModels}">
        <ItemsRepeater.ItemTemplate>
            <DataTemplate x:DataType="local:ViewModel">
                <TextBlock Text="{x:Bind Text}" />
            </DataTemplate>
        </ItemsRepeater.ItemTemplate>
    </ItemsRepeater>
</Page>

大部分情况下,写到这种程度就能完成任务了。但有时候需要把外部的成员(如OuterMember)传给DataTemplate内的控件(如此处的TextBlock),那么如何实现呢?

首先可以发现,在DataTemplate内并非只能使用ViewModel类的成员,而还能访问以下这些东西:

  • static成员

  • StaticResource

  • 事件处理方法

据此我们就可以利用这些来实现跨域(scope)访问类实例成员。一共有三种思路:

解决方案

Static转实例

这是很常用的方法,就连官方库都可以看到这样的实现,例如Application.Current

那我们可以仿照这样写:

public sealed partial class SamplePage : Page
{
    public static SamplePage Current { get; private set; }

    public SamplePage()
    {
        Current = this;
        ...
    }
    ...
}

此时在XAML中就可以:

...
<DataTemplate x:DataType="local:ViewModel">
    <TextBlock Text="{x:Bind local:SamplePage.Current.OuterMember}" />
</DataTemplate>
...

这样写的优点是简洁明了,缺点是只能单例使用

StaticResource

这种方法也有人使用:

public class Box
{
    public object Content { get; set; }
}

public sealed partial class SamplePage : Page
{
    public SamplePage()
    {
        ...
        InitializeComponent();
        ((Box)Resources["Box"]).Content = OuterMember;
    }
    ...
}
...
<Page.Resources>
    <local:Box x:Key="Box" />
    <local:UnboxConverter x:Key="UnboxConverter" />
</Page.Resources>
<ItemsRepeater ItemsSource="{x:Bind ViewModels}">
    <ItemsRepeater.ItemTemplate>
        <DataTemplate x:DataType="local:ViewModel">
            <TextBlock Text="{Binding Converter={StaticResource UnboxConverter}, ConverterParameter={StaticResource Box}}" />
        </DataTemplate>
    </ItemsRepeater.ItemTemplate>
</ItemsRepeater>
...

Box是用来装箱的,防止使用值类型时复制赋值导致前后不是同一个对象。

这种方法优点是十分灵活,处理方法写在Converter里,传递参数写在Box里,可以随意扩展,几乎没有限制。

缺点也很明显,写了许多不明所以的代码,逻辑曲折难懂,Binding效率也较差。

事件处理

这种方法可以很方便地获取需要的参数,但可能需要多写一个子控件:

public sealed partial class SampleControl : UserControl
{
    public event Func<SamplePage>? ThisRequested;

    public string? GetOuterMember => ThisRequested?.Invoke().OuterMember;

    public SampleControl()
    {
        InitializeComponent();
    }
}
<UserControl
    x:Class="SampleApp.SampleControl"
    ...>
    <TextBlock Text="{x:Bind GetOuterMember}" />
</UserControl>

原页面只需:

public sealed partial class SamplePage : Page
{
    private SamplePage MyControlOnThisRequested() => this;
    ...
}
...
<DataTemplate x:DataType="local:ViewModel">
    <local:SampleControl ThisRequested="MyControlOnThisRequested"/>
</DataTemplate>
...

这种方法十分优雅,也很灵活,缺点是要单独写一个子控件。但如果由于DataTemplate内容太长,本来就打算分开写控件,那这个缺点就不存在了。

总之三个方法各有利弊,大家可以根据需要选择最合适的。文章来源地址https://www.toymoban.com/news/detail-788590.html

到了这里,关于XAML中DataTemplate变量隐藏的解决方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WPF国际化的实现方法(WpfExtensions.Xaml)

    https://blog.csdn.net/eyupaopao/article/details/120090431 resx资源文件实现 resx资源文件,实现的过程比第一种复杂,但resx文件本身编辑比较简单,维护起来比较方便。需要用到的框架:WpfExtensions.Xaml 为每种语言添加.resx资源文件,放在I18nResource文件夹下 I18nResource.resx 代表英语,名字不要

    2024年02月12日
    浏览(24)
  • Git - 导出(archive)、忽略(gitignore)、隐藏(Stash)、合并冲突(merge)的解决方法

    本次集中总结了Git4个常规操作,导出(archive)、忽略(gitignore)、隐藏(Stash)、合并冲突(merge)的解决方法,希望帮助到正在辛苦寻找的你。 .gitignore忽略文件 之前开发和部署服务比较仓促,所以有很多图片文件一起加载到服务中,使得仓库代码922M,所以要分离出图片和忽略部分,

    2024年02月07日
    浏览(30)
  • Dedecms网站Title标签SEO优化方法

    现在百度基本上都不看keyword了(当然我们不能不写),目前的SEO优化大家都着重放在title上,那么对于dedecms网站的title该如何优化呢?下面就跟随小编一起来看看吧! 主要是涉及到一个如何实现\\\"三级栏目_二级栏目_一级栏目_网站名称\\\"的问题。yii666的title基本上是这样做的:

    2024年02月03日
    浏览(50)
  • dede5.7修改标题title长度方法总结

    当我们大家好DEDE5.7CMS系统以后,添加资料的时候回发现官方默认的标题长度非常的短,从截图我们能看到默认长度是60,这个不能满足我们发内容的需求,所以我们要针对性的修改一下。 这里按照小编的经验,大家可以直接修改成200-255之间的字符长度,能够满足网站的标题

    2024年02月02日
    浏览(34)
  • WPF之浅谈数据模板(DataTemplate)

    简而言之,数据模板能让你更方便、更灵活的显示你的各类数据。只有你想不到,没有它做不到的(感觉有点夸张,实践之后,你就觉得一点不夸张 😎)。 直接对比下效果: 无数据模板 应用了数据模板 好了,下面我们一步一步来看看数据模板如何做到化腐朽为神奇的!

    2024年02月08日
    浏览(28)
  • 关于嵌入式Qt5配置环境变量导致鼠标显示与隐藏

            不写QT_QPA_EVDEV_MOUSE_PARAMETERS环境变量则不显示鼠标,反之,环境变量配置正确则显示鼠标 如设置 Qt环境变量 就能显示鼠标。 在交叉编译并移植Qt-Embedded后,在开发板中配置环境变量如下 运行程序后,程序能正常运行,也能正常触摸点击,就是没有鼠标显示 以往

    2024年02月10日
    浏览(55)
  • pytorch3d旋转矩阵转四元数transforms.matrix_to_quaternion函数隐藏的大坑及其解决方法

      在pytorch旋转矩阵转四元数及各种旋转表示方式之间的转换实现代码这篇博客里,我提到可以使用pytorch3d实现批量旋转表示方法之间的转换。但是最近在使用它的matrix_to_quaternion函数的时候,发现了一个隐藏的巨大bug:它不会确保输出的四元数中的那个实数w恒为正。这样就

    2024年02月13日
    浏览(34)
  • 详解织梦DedeCMS栏目页分页标题Title添加“第N页”的方法

    织梦DedeCMS栏目页的标题,不管是第几页都是不变的,不利于网站的SEO,那么我们可以在分页的Title里加上第几页。 方法如下: 1.首先打开include/arc.listview.class.php文件.在文件中搜索: 并将其删除掉. 2.然后查找, 在他之前添加下面代码片段 3.打开织梦模板的列表页(list_article.htm、

    2024年02月02日
    浏览(34)
  • 已解决org.springframework.web.bind.MissingPathVariableException缺失路径变量异常的正确解决方法,亲测有效!!!

    已解决org.springframework.web.bind.MissingPathVariableException缺失路径变量异常的正确解决方法,亲测有效!!! 目录 问题分析 出现问题的场景 报错原因 解决思路 解决方法 总结 在开发Spring Boot Web应用时,我们常常需要通过URL传递参数。这些参数可以通过路径变量(Path Variables)的形

    2024年03月21日
    浏览(34)
  • MATLAB中CVX工具箱解决凸优化问题的基本知识——语法、变量声明、目标函数、约束条件、cvx编程错误及解决方法

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本文是在最近学习MATLAB CVX工具箱解决凸优化问题时学到的一些知识点,分享出来供大家参考。 进行CVX编程时,会遇到各种各样意想不到又难以解决的报错问题,如果编程过程中遇到了很多cvx bug和错误,

    2024年02月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包