开发者

Binding to second property if first is null in Silverlight

开发者 https://www.devze.com 2023-04-04 03:38 出处:网络
I have a class in which the name of the object can be null. public开发者_如何学Python class Thing

I have a class in which the name of the object can be null.

public开发者_如何学Python 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; }
}

In a Silverlight ListBox, I use a DataTemplate where I have the name bound to a TextBlock:

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

However, this obviously doesn't look very good if the Name is null. Ideally, I would want to use something equivalent to

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

but I can't change my model object. Is there any good way to do this?

I thought about using a Converter, but it seems to me I'd have to bind the converter to the object itself, and not the Name property. This would be fine, but how would I then rebind when either Name or Identifier changes? IValueConverter doesn't appear to have any way to force a reconvert if I would manually listen on my object's INotifyPropertyChanged event.

Any ideas on the best way to do this?


You can change the Binding, so that it binds directly to your Thing instance:

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

Then use a converter that returns either Instance or Name from the passed Thing instance

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


In WPF, you can do this easily by implementing an IMultiValueConverter. Unfortunately, Silverlight doesn't support this directly, though there are workarounds written for Silverlight.


The Converter is not bind to Name or Object, it binds to Text property binding. So, it will be invoked every time you assign a value to Text. Up to you after inside a Converter to choice what Text property will look like.

One of possible solutions is to make NameAndIdentifier string special property which is assignable from Converter based on Model's Name and Identifier properties.


You need to create a custom display property in your ViewModel/Presenter (or whatever you want to call it). Basically, the code you posted above must be modified, and this added to it:

public readonly string DisplayName
{
    get
    {
        return Name ?? Identifier;
    }
}

Any other way, as far as I know, is going to be a hack.

0

精彩评论

暂无评论...
验证码 换一张
取 消