如何在不更改视图模型的属性 getter 的情况下格式化 XAML 中的字符串?

2023-12-09

我的应用程序中有以下界面:

public interface IContactMedium
{
    string ContactString { get; set; }
    string Type { get; set;}
    bool IsValid();
}

该接口适用于代表某人某种联系的对象。它可以是电话、电子邮件等。ContactStringproperty 是实际的联系数据(例如,对于电话,它是电话号码),并且Type用于区分一个人拥有多个电话(对于电话,一个人可以拥有家庭电话、工作电话、手机等)IsValid方法是针对每种不同类型的接触介质的验证机制。

所以,假设我的应用程序中有两个对象 -Email and Phone- 两者都实现接口。我要在应用程序中创建一个UserControl它拥有一个管理此类对象列表的 UI。所以视图模型看起来像这样:

public class ContactsCollectionViewModel<T> : ViewModelBase where T : class, IContactMedium
{
    private ObservableCollection<T> _itemsCollection;

    public ContactCollectionViewModel(ObservableCollection<T> items)
    {
        ItemsCollection = items;
    }

    public ObservableCollection<T> ItemsCollection
    {
        get { return _itemsCollection; }
        set
        {
            if (_itemsCollection != value)
            {
                _itemsCollection = value;
                OnPropertyChanged(() => ItemsCollection);
            }
        }
    }
}

我想添加到IContactMedium接口另一个属性/方法,为ContactString在 WPF 中的绑定中使用时的属性。这个想法是文本框中的格式绑定到ContactString根据实际存储在集合中的具体对象而有所不同:

<TextBox x:Name="ContactString"
         Text="{Binding ContactString, StringFormat=???}" />

我在网上搜索了这个问题的解决方案,但找不到任何东西。我看到有人建议修改ContactString属性,以便 getter 返回一个格式化的值。所以,对于Phone例如,对象的属性如下所示:

public string ContactString
{
    get 
    {
        return string.Format("({0}) {1}-{2}", _contactString.Substring(0,3), _contactString.Substring(4,3), _contactString.Substring(7,3));
    }
    set {
        _contactString = value;
    }
}

然而,这对我来说不是一个好的解决方案。该信息不仅由 UI 使用。它还会发送到应用程序的其他部分,包括需要原始形式电话号码的数据库:##########。

有没有办法为 XAML 提供一个格式化程序以在StringFormat绑定的属性?格式可以由实现接口的对象决定吗?如果是,它需要是什么类型,以及如何使其可供访问Binding在 XAML 中?


格式可以由实现接口的对象决定吗?

在 Xaml 中,可以提供与特定类关联的数据模板。

只需在模板中的结构中提供绑定到目标属性的格式,如下所示:

<Grid>
    <Grid.Resources>
        <DataTemplate DataType="{x:Type c:Ship}">
            <TextBlock Text="{Binding Path=Name, StringFormat=Ship: {0}}"
                        Foreground="Red" />
        </DataTemplate>
        <DataTemplate DataType="{x:Type c:Passage}">
            <TextBlock Text="{Binding Path=Name, StringFormat=Passage: {0}}"
                        Foreground="Blue" />
        </DataTemplate>
    </Grid.Resources>
    <ListBox Name="myListBox"
             Height="300"
             Width="200"
             ItemsSource="{Binding OBSCollection}">
    </ListBox>
</Grid>

所以对于我的集合来说,两个类实例Ship and Passage坚持ITreeEntity:

 public ObservableCollection<ITreeEntity> OBSCollection ...

当绑定创建一个列表时,绑定具有特定的字符串格式,如下所示:

enter image description here

请注意,在设置数据时,首先添加船只,然后添加通道。无论如何,Xaml 不会对它们进行排序。


需要在一个 ListBox 中从复合集合中列出不同类型的对象?在这里查看我的答案:

  • 复合集合列表框答案
  • 列表框和模板的基本示例
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在不更改视图模型的属性 getter 的情况下格式化 XAML 中的字符串? 的相关文章

  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • 如何向 Mono.ZeroConf 注册服务?

    我正在尝试测试 ZeroConf 示例http www mono project com Mono Zeroconf http www mono project com Mono Zeroconf 我正在运行 OpenSuse 11 和 M
  • 用于在标头更改时重新编译的简单 C 项目的示例 makefile

    有谁有完整的 makefile 可以执行以下操作 如果 HEADER 文件发生更改 则重建项目 cpp 文件在 makefile 中列出 头文件未在 makefile 中列出 头文件允许与 cpp 文件具有不同的名称 部分cpp文件没有头文
  • Linux 上的 RTLD_LOCAL 和dynamic_cast

    我们有一个由应用程序中的一些共享库构成的插件 我们需要在应用程序运行时更新它 出于性能原因 我们在卸载旧插件之前加载并开始使用新插件 并且只有当所有线程都使用旧插件完成后 我们才卸载它 由于新插件和旧插件的库具有相同的符号 我们dlopen
  • LinkLabel 无下划线 - Compact Framework

    我正在使用 Microsoft Compact Framework 开发 Windows CE 应用程序 我必须使用 LinkLabel 它必须是白色且没有下划线 因此 在设计器中 我将字体颜色修改为白色 并在字体对话框中取消选中 下划线
  • 如何在 Javascript 中连接 C# ActiveX 事件处理程序

    我尝试使用几个代码片段将 ActiveX 对象与 Javascript 事件处理程序挂钩 我无法确定为什么事件处理程序没有被调用 带有项目的 Github 存储库 https github com JesseKPhillips Csharp
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 当Model和ViewModel一模一样的时候怎么办?

    我想知道什么是最佳实践 我被告知要始终创建 ViewModel 并且永远不要使用核心模型类将数据传递到视图 这就说得通了 让我把事情分开 但什么是Model 和ViewModel一模一样 我应该重新创建另一个类还是只是使用它 我觉得我应该重
  • 以编程方式创建 Blob 存储容器

    我有一个要求 即在创建公司时 在我的 storageaccount 中创建关联的 blob 存储容器 并将容器名称设置为传入的字符串变量 我已尝试以下操作 public void AddCompanyStorage string subDo
  • 使用 gcc 时在头文件中查找定义的好方法是什么?

    在使用 gcc 时 有人有推荐的方法在头文件中查找定义吗 使用 MSVC 时 我只需右键单击并选择 转到定义 这非常好 我使用过 netbeans gcc 它确实有代码帮助 包括到定义的超链接 所以这是一种选择 但是 我想知道是否有任何其他
  • 在哪里可以找到 Microsoft.Build.Utilities.v3.5

    如何获取 Microsoft Build Utilities v3 5 我正在使用 StyleCop 4 7 Stylecop dll 中的 StyleCop msbuild 任务似乎依赖于 Microsoft Build Utilitie
  • 调用 .ToArray() 时出现 ArgumentException

    我有一个经常被清除的列表 代码完全是这样的 VisitorAgent toPersist List
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • winform c# 中的弹出窗口

    我正在开发一个需要弹出窗口的项目 但问题是我还希望能够通过表单设计器在此弹出窗口中添加文本框等 所以基本上我有一个按钮 当您单击它时 它将打开我在表单设计器中设计的另一个窗口 我一直在谷歌搜索 但还没有找到我需要的东西 所以我希望你们能帮助
  • 声明一个负长度的数组

    当创建负长度数组时 C 中会发生什么 例如 int n 35 int testArray n for int i 0 i lt 10 i testArray i i 1 这段代码将编译 并且启用 Wall 时不会出现警告 并且似乎您可以分配
  • 如何在 ASP.NET Core 中注入泛型的依赖关系

    我有以下存储库类 public class TestRepository Repository
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐