如何在不更改视图模型的属性 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 中的字符串? 的相关文章

随机推荐