如果第一个属性在Silverlight中为空,则绑定到第二个属性

本文关键字:属性 绑定 第二个 第一个 Silverlight 如果 | 更新日期: 2023-09-27 18:08:26

我有一个类,它的对象名可以为空。

public class Thing
{
    /// <summary>
    /// The identifier of the thing
    /// </summary>
    /// <remarks>
    /// This will never be null.
    /// </remarks>
    public string Identifier { get; set; }
    /// <summary>
    /// The name of the thing
    /// </summary>
    /// <remarks>
    /// This MAY be null. When it isn't, it is more descriptive than Identifier.
    /// </remarks>
    public string Name { get; set; }
}

在Silverlight ListBox中,我使用了一个DataTemplate,其中我将名称绑定到一个TextBlock:

<DataTemplate x:Key="ThingTemplate">
    <Grid>
        <TextBlock TextWrapping="Wrap" Text="{Binding Name}" />
    </Grid>
</DataTemplate>

但是,如果Name为空,这显然看起来不太好。理想情况下,我想使用一些等价于

的东西
string textBlockContent = thing.Name != null ? thing.Name : thing.Identifier;

,但我不能改变我的模型对象。有什么好办法吗?

我考虑过使用转换器,但对我来说,我似乎必须将转换器绑定到对象本身,而不是Name属性。这很好,但是当Name或Identifier发生变化时,我该如何重新绑定呢?如果我手动监听对象的INotifyPropertyChanged事件,IValueConverter似乎没有任何方法强制重新转换。

有什么最好的办法吗?

如果第一个属性在Silverlight中为空,则绑定到第二个属性

您可以更改Binding,使其直接绑定到您的Thing实例:

<DataTemplate x:Key="ThingTemplate">
    <Grid>
        <TextBlock TextWrapping="Wrap" Text="{Binding .,Converter={StaticResource ConvertMyThingy}" />
    </Grid>
</DataTemplate>

然后使用从传递的Thing实例返回InstanceName的转换器

public class ConvertMyThingyConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var thing= value as Thing;
        if(thing == null)
           return String.Empty;
        return thing.Name ?? thing.Identifier;
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在WPF中,您可以通过实现multivalueconverter轻松地做到这一点。不幸的是,Silverlight并不直接支持此功能,尽管有为Silverlight编写的解决方案。

Converter不绑定到NameObject,它绑定到Text属性绑定。因此,每次向Text赋值时都会调用它。在Converter中,您可以选择Text属性的外观。

一种可能的解决方案是使NameAndIdentifier字符串具有特殊属性,该属性可以基于Model的NameIdentifier属性从Converter中分配。

你需要在你的ViewModel/Presenter(或者你想叫它什么)中创建一个自定义的显示属性。基本上,您上面发布的代码必须修改,并添加以下内容:

public readonly string DisplayName{得到{返回名称??标识符;}} 之前

据我所知,任何其他方法都将是一个hack。