目前我遇到了问题,我的业务对象会覆盖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}" />
非常感谢!
答案 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()
覆盖而没有任何值更新通知机制,这将是令人惊讶的。