【问题标题】:Binding to a derived property without proxy object in WPF MVVM在 WPF MVVM 中绑定到没有代理对象的派生属性
【发布时间】:2012-05-03 12:27:18
【问题描述】:

假设我有一个类似的域模型:

class User  {
    public string FirstName  { get; set; }
    public string LastName   { get; set; }
    public string MiddleName { get; set; }
    public int    Age        { get; set; }
    // tons of other stuff
}

我有一个名为UserListObservableCollection,我将其绑定到这样的DataGrid:

<dg:DataGrid ItemsSource="{Binding Path=UserList}" SelectedIndex="{Binding Path=Selecteduser}">
    <dg:DataGrid.Columns>
        <dg:DataGridTextColumn Header="Name" Binding="{Binding Path=FirstName, Mode=OneWay}" />
        <dg:DataGridTextColumn Header="Age" Binding="{Binding Path=Age, Mode=OneWay}" />
    </dg:DataGrid.Columns>
</dg:DataGrid>

现在我决定为用户的全名添加一个网格列。我的User 对象没有这个属性,但是如果你给我一个User 对象,它很容易计算出来。如何在我的User 对象上绑定到这样的派生“属性”,而无需为User 创建代理类(又名视图模型)并重写大量代码来处理此代理,将状态从域对象复制到代理对象等?

一个相当干净和明显的解决方案是扩展方法,但显然你不能绑定到它。

我只想告诉网格:对于这个列,给我一个用户和一些表明这是什么的键(例如“全名”),我会将数据传回给你用于列。

【问题讨论】:

    标签: .net wpf xaml mvvm wpfdatagrid


    【解决方案1】:

    您当然可以通过这样的多重绑定来创建大部分派生属性:

    <DataGridTextColumn Header="FullName">
        <DataGridTextColumn.Binding>
            <MultiBinding StringFormat="{}{0} {1}}">
                <Binding Path="FirstName"/>
                <Binding Path="LastName"/>
            </MultiBinding>
        </DataGridTextColumn.Binding>
    </DataGridTextColumn>
    

    对于更复杂的事情,您可能必须直接绑定到 User 对象并使用带有转换器参数的 binding converter 来创建派生值:

    public class UserConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            User user = (User)value;
            string result = string.Empty;
    
            switch ((string)parameter)
            {
                case "FullName":
                    result = string.Format("{0} {1}", user.FirstName, user.LastName);
                    break;
            }
    
            return result;
        }
    
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    

    然后像这样绑定:

    <DataGridTextColumn Header="FullName"
        Binding="{Binding Converter={StaticResource UserConverter}, ConverterParameter=FullName}"/>
    

    【讨论】:

    • MultiBinding StringFormat 非常适合我的示例案例,但不适用于我的实际案例(这不仅仅是字符串格式),但很高兴知道这一点。但是,IValueConverter 正是医生订购的。 :) 任何 WPF 程序员可能已经知道的东西,但我在一个不熟悉的代码库中蒙混过关。我认为这样的东西一定存在,但不知道它会是什么样子。我昨天的谷歌搜索把我带到了IValueConverter,但我错过了绑定字符串。谢谢。 :)
    猜你喜欢
    • 2020-04-01
    • 1970-01-01
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多