uri*_*ini 13 c# data-binding wpf converter
为什么当我在WPF中的绑定表达式中使用转换器时,在更新数据时不会更新该值.
我有一个简单的Person数据模型:
class Person : INotifyPropertyChanged
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我的绑定表达式如下所示:
<TextBlock Text="{Binding Converter={StaticResource personNameConverter}" />
Run Code Online (Sandbox Code Playgroud)
我的转换器看起来像这样:
class PersonNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Person p = value as Person;
return p.FirstName + " " + p.LastName;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我在没有转换器的情况下绑定数据,那么效果很好
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
编辑:只是为了澄清一些事情,Joel和Alan对于需要实现的INotifyPropertyChanged接口都是正确的.实际上我确实实现了它,但它仍然无效.
我不能使用多个TextBlock元素,因为我正在尝试将Window Title绑定到全名,而Window Title不会使用模板.
最后,可以选择添加复合属性"FullName"并绑定到它,但我仍然想知道为什么绑定使用转换器时不会发生更新.即使我在转换器代码中设置了一个断点,当对底层数据进行更新时,调试器也无法实现:-(
谢谢,乌里
Arc*_*rus 14
您还可以使用MultiBinding ..绑定到Person对象,FirstName和LastName.这样,只要FirstName或LastName抛出属性更改事件,该值就会更新.
<MultiBinding Converter="{IMultiValueConverter goes here..}">
<Binding />
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
Run Code Online (Sandbox Code Playgroud)
或者,如果您只使用FirstName和LastName,则将Person对象从绑定中剥离为以下内容:
<MultiBinding Converter="{IMultiValueConverter goes here..}">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
Run Code Online (Sandbox Code Playgroud)
MultiValueConverter看起来像这样:
class PersonNameConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return values[0].ToString() + " " + values[1].ToString();
}
public object ConvertBack(object[] values, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当然,所选答案也可以,但MultiBinding的工作更优雅......
Joe*_*ant 11
(见下面的编辑;最新:#2)
它没有更新,因为您的Person对象无法通知任何值FirstName或LastName已更改的内容.看到这个问题.
以下是您的实施方式INotifyPropertyChanged.(更新,请参阅编辑2)
using System.ComponentModel;
class Person : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
string _firstname;
public string FirstName {
get {
return _firstname;
}
set {
_firstname = value;
onPropertyChanged( "FirstName", "FullName" );
}
}
string _lastname;
public string LastName {
get {
return _lastname;
}
set {
_lastname = value;
onPropertyChanged( "LastName", "FullName" );
}
}
public string FullName {
get {
return _firstname + " " + _lastname;
}
}
void onPropertyChanged( params string[] propertyNames ) {
PropertyChangedEventHandler handler = PropertyChanged;
if ( handler != null ) {
foreach ( var pn in propertyNames ) {
handler( this, new PropertyChangedEventArgs( pn ) );
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑1
实际上,由于你是在更名的第一个名字和名字之后,Path=FirstName并且这样的工作很好,我认为你根本不需要转换器.多个TextBlocks同样有效,并且当您使用从右到左的语言本地化时,实际上可以更好地工作.
编辑2
我已经明白了.没有通知属性已更新,因为它绑定到对象本身,而不是其中一个属性.即使我做Person了一个DependencyObject和制作FirstName和LastName DependencyProperties,它不会更新.
你将不得不使用一个FullName属性,我已经更新了Person上面的类的代码来反映这一点.然后你可以绑定Title.(注意:我已将Person对象设置为Window's DataContext.)
Title="{Binding Path=FullName, Mode=OneWay}"
Run Code Online (Sandbox Code Playgroud)
如果您正在编辑a中的名称TextBox并希望立即反映名称而不是TextBox失去焦点,则可以执行以下操作:
<TextBox Name="FirstNameEdit"
Text="{Binding Path=FirstName, UpdateSourceTrigger=PropertyChanged}" />
Run Code Online (Sandbox Code Playgroud)
我知道你不想使用一个FullName属性,但任何可以实现你想要的东西都可能是一个Rube Goldberg设备.如实施INotifyPropertyChanged和Person对房地产Window类本身,具有Window侦听PropertyChanged,以触发事件Window的PropertyChanged事件,并使用相对类似下面结合.您也可以在设置Person属性之前设置属性,InitializeComponent()或者PropertyChanged在设置Person属性后触发,以便它显示出来.(否则它将在null期间InitializeComponent()并且需要知道它何时是Person.)
<Window.Resources>
<loc:PersonNameConverter
x:Key="conv" />
</Window.Resources>
<Window.Title>
<Binding
RelativeSource="{RelativeSource Self}"
Converter="{StaticResource conv}"
Path="Person"
Mode="OneWay" />
</Window.Title>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24711 次 |
| 最近记录: |