如何格式化XAML字符串不改变视图模型的属性的getter? [英] How to format a string in XAML without changing viewmodel's property getter?

查看:164
本文介绍了如何格式化XAML字符串不改变视图模型的属性的getter?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序如下界面:

 公共接口IContactMedium 
{
串ContactString {搞定;组; }
字符串类型{搞定;设置;}
BOOL的IsValid();
}

这接口是代表某种对一个人接触的对象。它可以是一个电话,电子邮件等的 ContactString 属性是实际接触数据(为一个电话,例如,这将是该电话号码),以及在键入是分化的情况下,一个人有一个以上的(对于电话,一个人可以有一个家庭电话,办公电话,手机等)的IsValid 方法对于每个不同类型的接触介质的验证机制。



所以,让我们说我在我的应用程序的两个对象 - 电子邮件电话 - 既实现的接口。我打算在应用程序中做出用户控件持有,管理这样的对象列表的UI。因此,视图模型将是这个样子:

 公共类ContactsCollectionViewModel< T> :ViewModelBase其中T:类,IContactMedium 
{
私人的ObservableCollection< T> _itemsCollection;

公共ContactCollectionViewModel(的ObservableCollection< T>项目)
{
ItemsCollection =物品;
}

公众的ObservableCollection< T> ItemsCollection
{
{返回_itemsCollection; }

{
如果(!_itemsCollection =值)
{
_itemsCollection =价值;
OnPropertyChanged(()=> ItemsCollection);
}
}
}
}



我要添加到 IContactMedium 接口的另一属性/方法在绑定使用时提供了 ContactString 属性正确的格式WPF。我们的想法是,在绑定到 ContactString 文本框格式不同取决于实际存储集合中的具体对象上:

 <文本框X:NAME =ContactString
文本={结合ContactString,的StringFormat = ???}/>



我在网上搜索了一个解决方案,但没有找到任何东西。我看到有人建议修改 ContactString 属性,以便吸气返回格式化的值。因此,对于电话对象,例如,属性是这样的:

 公共字符串ContactString 
{
得到
{
返回的String.Format(({0}){1} - {2},_contactString.Substring( 0,3),_contactString.Substring(4,3),_contactString.Substring(7,3));
}
集合{
_contactString =价值;
}
}



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



有没有提供一个XAML格式在绑定的的StringFormat 属性使用的方法吗?可以格式化由实现接口的对象所支配?如果是的话,它需要什么类型的是,我怎么可以让它访问到绑定在XAML?


解决方案

的事情是,实现该接口将有不同的格式规则


$ b $每个具体类b



能否格式化被实现该接口的对象所决定?




的两难困境是,是否将格式化逻辑添加到您的业务对象( IContactMedium 实施),或表示层。



如果是业务逻辑,那么,你应该格式化代码添加到您的业务对象。



不过,最有可能是表现逻辑。在这种情况下,无论是创建 IContactMedium ,或者创建转换器的DataTemplate的foreach执行。在该转换器可以选择基于价值类型正确的格式。如果输出仅仅是纯文本,使用转换器。如果它更多的是纯文本,如格式化文本,使用的DataTemplates



提示:您可以使用单元测试来测试,如果所有的实现 IContactMedium 有它的DataTemplate或由转换器所覆盖。


I have in my application the following interface:

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

This interface is for objects that represent some sort of contact for a person. It could be a phone, email, etc. The ContactString property is the actual contact data (for a phone, for example, it would be the phone number), and the Type is for differentiation in case a person has more than one (for phone, a person can have a Home phone, a Work phone, Cell phone, etc.) The IsValid method is a validation mechanism for each different type of contact medium.

so, let's say I have two objects in my application - Email and Phone - both implement the interface. I'm going to make in the application a UserControl that holds a UI that manages a list of such objects. So the viewmodel would look something like this:

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);
            }
        }
    }
}

I want to add to the IContactMedium interface another property/method that provides proper formatting for the ContactString property when used in Binding in WPF. The idea is that the format in the text box bound to ContactString differs depending on the concrete object that is actually stored in the collection:

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

I searched online a solution for this and couldn't find anything. I saw people suggesting modifying the ContactString property so the getter returns a formatted value. So, for the Phone object, for example, the property would look like this:

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;
    }
}

However, this is not a good solution for me. The information is not only used by the UI. It is also sent to other parts of the application, including a database, that need the phone number in its raw form: ##########.

Is there a way to provide the XAML a formatter to use in the StringFormat attribute of the binding? Can the formatting be dictated by the object that implement the interface? If yes, what type does it need to be, and how can I make it accessible to the Binding in XAML?

解决方案

The thing is that each concrete class that implements the interface would have different formatting rules

Can the formatting be dictated by the object that implement the interface?

The dilema is, whether to add the formating logic to your business objects (IContactMedium implementations) or to presentation layer.

if it is business logic, then yes, you should add the formatting code to your business object.

But most probably it is presentation logic. In that case, either create DataTemplate foreach implementation of the IContactMedium, or create converter. In the converter you can choose correct formatting based on the value type. If the output is just plain text, use converter. If its more that plain text, e.g formatted text, use datatemplates.

TIP: You can use unit tests to test if all implementations of IContactMedium have its DataTemplate or are covered by the converter.

这篇关于如何格式化XAML字符串不改变视图模型的属性的getter?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆