Привязка ко второму свойству, если first равно нулю в Silverlight - PullRequest
3 голосов
/ 12 сентября 2011

У меня есть класс, в котором имя объекта может быть нулевым.

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

В ListBox Silverlight я использую DataTemplate, где у меня есть имя, привязанное к TextBlock:

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

Однако это, очевидно, выглядит не очень хорошо, если Имя равно нулю. В идеале я хотел бы использовать что-то эквивалентное

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

но я не могу изменить свой модельный объект. Есть ли хороший способ сделать это?

Я думал об использовании конвертера, но мне кажется, что мне придется привязать конвертер к самому объекту, а не к свойству Name. Это было бы хорошо, но как мне тогда перепривязать, когда изменится либо Имя, либо Идентификатор? У IValueConverter, кажется, нет никакого способа заставить преобразование, если бы я вручную прослушивал событие INotifyPropertyChanged моего объекта.

Есть идеи, как лучше всего это сделать?

Ответы [ 4 ]

3 голосов
/ 12 сентября 2011

Вы можете изменить привязку, чтобы она связывалась непосредственно с вашим экземпляром Thing:

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

Затем используйте конвертер, который возвращает либо Instance, либо Name из переданного Thing экземпляра

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();
    }
}
2 голосов
/ 12 сентября 2011

В WPF это легко сделать, внедрив IMultiValueConverter . К сожалению, Silverlight не поддерживает это напрямую, хотя для Silverlight написано обходных путей.

0 голосов
/ 12 сентября 2011

Вам необходимо создать собственное свойство отображения в вашей ViewModel / Presenter (или как вы хотите его называть). По сути, код, который вы разместили выше, должен быть изменен, и это добавлено к нему:

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

Любой другой способ, насколько я знаю, будет взломать.

0 голосов
/ 12 сентября 2011

Converter не привязан к Name или Object, он привязан к Text привязке свойства.Таким образом, он будет вызываться каждый раз, когда вы присваиваете значение Text.После того, как вы внутри Converter выберете, как будет выглядеть Text свойство.

Одно из возможных решений - создать специальное свойство NameAndIdentifier string, которое можно назначать из Converter на основе Name модели.и Identifier свойства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...