Change binding if value is empty

落爺英雄遲暮 提交于 2019-12-24 05:40:06

问题


I want to change binding if the value is null or empty.

I make this exemple to explain :

List<test> list = new List<test>();
list.Add(new test { Name1 = "Bill", Name2 = "Jack" });
list.Add(new test { Name1 = "", Name2 = "Adam" });
TestDataGrid.ItemsSource = list;

XAML

<DataGridTextColumn Header="Name" Binding="{Binding Name1}" />

in this case will show :

Bill

""

I want if the first name is null or empty will show the Name2, then

Bill

Adam

in another way I want to do :

<DataGridTextColumn Header="Name" Binding="if({Binding Name1} == null)
                                  {Binding Name2} else {Binding Name1}   " />

edit

I thing that Converter resolve that, but I can't send the Name2 to change the value if the Name1 is null


回答1:


I'd create a new property:

public string Name { get { return string.IsNullOrEmpty(Name1) ? Name2 : Name1; } }

<DataGridTextColumn Header="Name" Binding="{Binding Name}" />



回答2:


A PriorityBinding could be used for this. It attempts multiple bindings until one succeeds. A converter that returns UnsetValue is considered a failed binding, so you could use one such as:

public class EmptyToUnsetConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if (string.IsNullOrEmpty(value as string))
            return DependencyProperty.UnsetValue;

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return DependencyProperty.UnsetValue;
    }
}

And apply it to each binding:

<DataGridTextColumn Header="Name">
    <DataGridTextColumn.Binding>
        <PriorityBinding>
            <Binding Path="Name1" Converter="{StaticResource EmptyToUnsetConverter}" />
            <Binding Path="Name2" Converter="{StaticResource EmptyToUnsetConverter}" />
        </PriorityBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

This would be more useful if you were working with different types of bindings or bindings from different sources and so on. For a collection of names, you might as well just wrap them with another property as others have shown.




回答3:


You can use MultiBinding to get both values into the converter:

<DataGridTextColumn Header="Name" 
    <DataGridTextColumn.Binding>
        <MultiBinding Converter="{StaticResource NameConverter}">
            <Binding Path="Name1" />
            <Binding Path="Name2" />
        </MultiBinding>
    </DataGridTextColumn.Binding>
</DataGridTextColumn>

The "NameConverter" should be an IMultiValueConverter, which takes multiple values as inputs:

public class NameConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        string name1 = values.ElementAtOrDefault(0) as string, 
            name2 = values.ElementAtOrDefault(1) as string;
        return name1 ?? name2;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

MultiBinding is a nifty approach, but in this case you may find it more convenient to simply add another read-only property "DisplayName" to your "test" class:

public class test
{
    public string Name1 { get; set; }
    public string Name2 { get; set; }

    public string DisplayName { get { return Name1 ?? Name2; } }
}



回答4:


Maybe the easiest solution would be to add in a custom property DisplayName, say, and just write code for it's Get()?



来源:https://stackoverflow.com/questions/23275092/change-binding-if-value-is-empty

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!