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

发布于 2024-12-03 23:45:15 字数 1180 浏览 1 评论 0原文

我有一个类,其中对象的名称可以为空。

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>

但是,如果名称为 null,这显然看起来不太好。理想情况下,我想使用相当于

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

但我无法更改我的模型对象的东西。有什么好的方法可以做到这一点吗?

我考虑过使用转换器,但在我看来,我必须将转换器绑定到对象本身,而不是 Name 属性。这很好,但是当名称或标识符更改时我将如何重新绑定?如果我手动侦听对象的 INotifyPropertyChanged 事件,IValueConverter 似乎没有任何方法强制重新转换。

关于最好的方法有什么想法吗?

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

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅暮の光 2024-12-10 23:45:15

您可以更改绑定,以便它直接绑定到您的 Thing 实例:

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

然后使用一个转换器,从传递的参数中返回 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();
    }
}

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();
    }
}
过潦 2024-12-10 23:45:15

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.

清风夜微凉 2024-12-10 23:45:15

Converter 未绑定到 NameObject,它绑定到 Text 属性绑定。
因此,每次为 Text 赋值时都会调用它。由您在 Converter 内部选择 Text 属性的外观。

可能的解决方案之一是创建 NameAndIdentifier 字符串特殊属性,该属性可根据模型的 NameIdentifier 属性从 Converter 分配。

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.

幸福不弃 2024-12-10 23:45:15

您需要在 ViewModel/Presenter(或任何您想要的名称)中创建一个自定义显示属性。基本上,您上面发布的代码必须进行修改,并且添加了以下内容:

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

据我所知,任何其他方式都将是一种黑客行为。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文