我目前在使用WPF MVVM数据绑定时遇到了一个奇怪的问题。
这个想法是使用ValueConverter,如果它不是null,则显示绑定值,否则显示ConverterParameter
中定义的字符串。Person
类,具有以下属性:Name (string)
、Surname (string)
、Country (class)
。Country
类具有以下属性:CountryName (string)
。
如果Person.Country
为null,则TextBlock绑定到Person.Country.CountryName
时,IValueConverter
使用失败。IValueConverter
方法Convert
甚至不触发来检查绑定值是否为null。
同时IMultiValueConverter
工作得很好,无论Person.Country
是否为null,每次都会触发。
为什么会这样呢?已尝试搜索任何Microsoft文章,但未找到任何内容。
任何帮助都很感激。
源GitHub项目可以在这里找到:https://github.com/kevintw86/WpfBindingConverterIssue.git
绑定到IValueConverter(当Person.Country==null):
<TextBlock
Text="{Binding Person.Country.CountryName,
UpdateSourceTrigger=PropertyChanged,
Converter={StaticResource PersonConverter},
ConverterParameter=- Not set -}"
FontSize="16"/>
PersonConverter:
public class PersonConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return parameter;
if (value == DependencyProperty.UnsetValue)
return parameter;
if (string.IsNullOrWhiteSpace(value.ToString()))
return parameter;
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
绑定到IMultiValueConverter(即使Person也可以正常工作。Country==null):
<TextBlock FontSize="16">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource PersonMultiConverter}"
ConverterParameter="- Not set -">
<MultiBinding.Bindings>
<Binding Path="Person.Country.CountryName"
UpdateSourceTrigger="PropertyChanged"/>
</MultiBinding.Bindings>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
PersonMultiConverter:
public class PersonMultiConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return parameter;
if (values[0] == DependencyProperty.UnsetValue)
return parameter;
if (values[0] == null)
return parameter;
if (string.IsNullOrWhiteSpace(values[0].ToString()))
return parameter;
return values[0];
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
人员类别:
public class Person : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
_Name = value;
OnPropertyChanged();
}
}
private string _Surname;
public string Surname
{
get { return _Surname; }
set
{
_Surname = value;
OnPropertyChanged();
}
}
private Country _Country;
public Country Country
{
get { return _Country; }
set
{
_Country = value;
OnPropertyChanged();
}
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
#endregion
}
国家类别:
public class Country : INotifyPropertyChanged
{
private string _CountryName;
public string CountryName
{
get { return _CountryName; }
set
{
_CountryName = value;
OnPropertyChanged();
}
}
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
#endregion
}
主窗口视图模型:
public class MainWindowViewModel : INotifyPropertyChanged
{
public MainWindowViewModel()
{
this.Person = new Person
{
Name = "John",
Surname = null,
Country = null,
};
}
#region Properties
private Person _Person;
public Person Person
{
get { return _Person; }
set
{
_Person = value;
OnPropertyChanged();
}
}
#endregion
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = "")
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
#endregion
}
1条答案
按热度按时间kjthegm61#
考虑使用TargetNullValue和FallbackValue代替转换器: