C#WPF绑定转换器如果绑定属性为null,则不发射

发布于 2025-01-24 01:24:18 字数 6108 浏览 1 评论 0原文

我目前使用WPF MVVM数据绑定面对奇怪的问题。

这个想法是使用valueConverter显示界值(如果其不为null),否则在ConverterParameter中显示字符串。

person与以下属性的类:name(string)sunname(string),,country> country(class)

country类具有以下属性:乡村名称(String)

ivalueconverter 失败当TextBlock绑定到person.country.country.countryname时,如果person.CONER.COUNTRITY是无效的。 ivalueconverter方法convert 甚至不触发以检查界值是否为null。

同时,imultivalUeconverter效果很好,每次触发person.country null null null null null null n null in n null noce> n均不已。

想法为什么如此?试图搜索任何Microsoft文章,但什么也没有发现。

任何帮助都将受到赞赏。

源GitHub项目可以在此处找到: https:// https://github.com/kevintw86/kevintw86/wpfbindingconverconverterissue.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结合(即使人也可以正常工作) ):

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

人力化verterter:

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
}

mainWindowViewModel:

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
}

I'm currently facing the strange issue using WPF MVVM data binding.

The idea is to use ValueConverter that displays bound value if its not null, otherwise displays string defined in ConverterParameter.

Person class with the following properties: Name (string), Surname (string), Country (class).

Country class has the following properties: CountryName (string).

The use of a IValueConverter fails when TextBlock is bound to a Person.Country.CountryName if the Person.Country is null. The IValueConverter method Convert even not firing to check if the bound value is null or not.

At the same time IMultiValueConverter works just fine, firing every time whether Person.Country null or not null.

Ideas why it is so? Tried to search for any Microsoft articles, but found nothing.

Any help is appreciated.

Source GitHub project may be found here: https://github.com/kevintw86/WpfBindingConverterIssue.git

Binding to IValueConverter (not working properly when 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();
        }
    }

Binding to IMultiValueConverter (works fine even if 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();
        }
    }

Person class:

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
}

Country class:

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
}

MainWindowViewModel:

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
}

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

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

发布评论

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

评论(1

丢了幸福的猪 2025-01-31 01:24:18

考虑使用而不是转换器:

<TextBlock 
      Text="{Binding Person.Country.CountryName, 
      TargetNullValue='- Not set -', 
      FallbackValue='- Not set -'}"

consider using TargetNullValue and FallbackValue instead of converter:

<TextBlock 
      Text="{Binding Person.Country.CountryName, 
      TargetNullValue='- Not set -', 
      FallbackValue='- Not set -'}"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文