WPF - 为ToString更改了Raise属性

时间:2015-11-18 10:23:37

标签: c# wpf xaml tostring telerik-grid

目前我遇到了问题,我的业务对象会覆盖ToString,以便将数据传送到某个telerik控件(RadListBox / RadListBoxItem)。覆盖ToString的模型实现INotifyPropertyChanged.是否可以在c#中提升要更改的方法ToString?初始值得到很好的显示,但稍后的更改将被忽略。例如:

public class ViewModel : UI.MVC.ViewModelBase
{
    private string name;

    [JsonProperty]
    public string Name
    {
        get
        {
            return name;
        }

        set
        {
            name = value;
            RaisePropertyChanged("Name");
        }
    }

    public override string ToString()
    {
        return name ?? "--";
    }
}

例如,如果Name被查询,则应调用ToString来获取新值。

修改

上面的ViewModel嵌入在另一个视图模型中。绑定到RadPropertyGrid

public class FirstViewModel :  : UI.MVC.ViewModelBase
{
    public FirstViewModel()
    {
        SelectedItem = new ViewModel();
    }

    public object SelectedItem
    {
        get;
    }
}

RistViewModel的一个实例是包含窗口的datacontext。

XAML

<telerik:RadPropertyGrid NestedPropertiesVisibility="Visible" 
    x:Name="propertyGrid" Grid.Column="1" Grid.Row="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsGrouped="True" 
    Item="{Binding SelectedItem,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

非常感谢!

1 个答案:

答案 0 :(得分:3)

  

是否可以在c#中引发要更改的ToString方法?

不,这是不可能的。您不能强制其他代码再次调用ToString()作为其他事件的直接后果。就此而言,INotifyPropertyChanged工作的唯一原因是,按照惯例,代码知道订阅该事件并在引发事件时调用属性getter(这是一种方法)。事件实际上并没有强制任何代码调用属性getter;只是任何打扰订阅该事件的人几乎肯定会在事件发生时调用该方法。

当然,您始终可以在所需的代码段之间设置任何机制。但对于代码本身没有理由相信它可能会从ToString()获得不同的结果,具体取决于它被调用的时间,这种机制不会存在。

  

例如,如果Name是chagned,则应调用ToString以获取新值。

您始终可以自己订阅INotifyPropertyChanged.PropertyChanged,然后执行某些操作以强制再次调用ToString()方法。从你提供的小代码中可以得出如何做到这一点并不清楚;可能会将SelectedItem设置为null,然后再返回到所需的对象。


所有这一切,虽然我不熟悉您正在使用的控件(RadPropertyGrid),假设它遵循正常的WPF模型,那么如果它实际上在某些显示SelectedItem对象方式,我猜它是这样做的,这种方式与DataTemplate类型的使用兼容。即如果您要为DataTemplate类声明ViewModel,则可以直接绑定到Name属性。例如:

<DataTemplate DataType="l:ViewModel">
    <TextBlock Text="{Binding Name}"/>
</DataTemplate>

...如果显示的名称发生变化,WPF会自动更新显示的名称。

您的ToString()方法提供的默认名称值为"--"。如果您愿意,可以将其合并到Name属性中,或者您可以添加新属性,例如DisplayName提供了这一点(例如,如果由于某种原因,您需要Name在未设置属性时保留null

如果没有a good, minimal, complete code example清楚地显示您正在做什么,就无法确定最佳方法是什么。但是,好的 WPF库不支持正常的绑定和模板机制,而是完全依赖于ToString()覆盖而没有任何值更新通知机制,这将是令人惊讶的。