在WPF C#绑定能见度转换器 [英] Binding Visibility Converter in WPF C#

查看:94
本文介绍了在WPF C#绑定能见度转换器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有类型的集合,当根据需要设置在屏幕上的某些控件的可见性计数其回调火灾的依赖项属性。

但仍然控制倒塌的所有的时间。
由于每code,一个控制仍然可见所有的时间。

XAML绑定是

 <{,转换器= {StaticResource的VisibilityConverter}绑定CountLabelVisibleReverse}的TextBlock文本=保证金=5,0,100,0能见度=106搜索A结果 />
 < StackPanel的Grid.Row =1方向=横向保证金=0,0,90,0
                            能见度={结合CountLabelVisible,转换器= {StaticResource的VisibilityConverter}}>
 < TextBlock的文本=排序依据/>
 <组合框样式={StaticResource的ComboBoxStyle1}WIDTH =100X:NAME =ComboBoxSorting的ItemsSource ={结合SortBy}/>
   < / StackPanel的>

我的两个属性是

 公共BOOL CountLabelVisible {搞定;组; }    公共BOOL CountLabelVisibleReverse {搞定;组; }

依赖属性回调

 私有静态无效ItemsCollectionChanged(OBJ的DependencyObject,DependencyPropertyChangedEventArgs EventArgs的)
    {
        VAR listingUserControl =(OBJ为ListingUserControl);        VAR itemsResult =(eventArgs.NewValue的名单,LT; ItemsResult>);
        如果(listingUserControl = NULL&放大器;!&安培;!itemsResult = NULL)
        {
            listingUserControl.CountLabelVisible = itemsResult.Count> 0;
            listingUserControl.CountLabelVisibleReverse = itemsResult.Count&下; = 0;
        }
    }

转换器code是

 公共对象转换(对象的值,类型TARGETTYPE,对象参数,System.Globalization.CultureInfo文化)
    {
        如果(参数== NULL)
            返回(布尔)值==假的? Visibility.Collapsed:Visibility.Visible;        返回(布尔)值? Visibility.Collapsed:Visibility.Visible;
    }


解决方案

您已经取得的结合是有效的约束力,但在变化,这意味着绑定子系统无法检测的更改不会通知自动属性的典型错误和更新的约束性指标。

要解决这个问题,实现 INotifyPropertyChanged的您视图模型,然后确保通知从属性的属性更改。

作为一个例子,我在为我的ViewModels基类以下内容:

 公共抽象类BaseViewModel:INotifyPropertyChanged的
{    ///<总结>
    ///助手方法来设置属性的值,并通知当值已更改。
    ///< /总结>
    ///< typeparam NAME =T>< / typeparam>
    ///< PARAM NAME =为newValue>到设置属性的值< /参数>
    ///< PARAM NAME =CurrentValue的方式>的属性的当前值< /参数>
    ///< PARAM NAME =通知>指示是,如果该值已更改应该通知< /参数>
    ///< PARAM NAME =通知>该属性的名称,以通知已更改< /参数>
    保护BOOL的SetProperty< T>(REF牛逼为newValue,裁判牛逼CurrentValue的,布尔通知,则params字符串[]通知)
    {
        如果(EqualityComparer< T> .Default.Equals(为newValue,CurrentValue的))
            返回false;        CurrentValue的=为newValue;
        如果(通知和放大器;&安培; notifications.Length大于0)
            的foreach(在通知字符串propertyName的)
                OnPropertyChanged(propertyName的);        返回true;
    }    ///<总结>
    ///引发的<见CREF =E:PropertyChanged的/>事件。
    ///< /总结>
    ///< PARAM NAME =PROPERTYNAME>更改属性的名称< /参数>
    保护无效OnPropertyChanged(字符串propertyName的)
    {
        如果(this.PropertyChanged!= NULL)
            this.PropertyChanged(这一点,新PropertyChangedEventArgs(propertyName的));
    }    ///<总结>
    ///时出现属性值的变化。
    ///< /总结>
    公共事件PropertyChangedEventHandler的PropertyChanged;}

然后在您的视图模型常规:

 公共类MyViewModel:BaseViewModel
{
    私人布尔_countLabelVisible;    公共BOOL CountLabelVisible
    {
        {返回_countLabelVisible; }
        集合{的SetProperty(参考值,参考_countLabelVisible,真的,CountLabelVisible,CountLabelVisibleReverse); }
    }    公共BOOL CountLabelVisibleReverse {{返回_countLabelVisible!; }}
}

这样,当 CountLabelVisible 得到改变,也通知对房地产 CountLabelVisibleReverse 和财产 CountLabelVisibleReverse 仅由一个getter的 - 因为它总是会逆 CountLabelVisible

这样修复您的code你有它的方式,但现实是,你不需要保持 CountLabelVisibleReverse 属性,而不是你可以:


  • 创建一个逆知名度转换器作为一个独立的转换器

  • 通过传递一个可选参数的结合
  • 创建一个多功能的知名度转换器
  • 堆叠多个转换器,其中,从一个转换器的输出被管道输送到下一个转换器的输入

I have a dependency property of type collection, when its callback fires based on the count I need to set the visibility of some of the controls on the screen.

But the controls remains Collapsed all the time. As per the code, one control remains visible all the time.

XAML binding is

   <TextBlock Text="106 search results for 'a'" Margin="5,0,100,0" Visibility="{Binding CountLabelVisibleReverse, Converter={StaticResource VisibilityConverter}}"/>
 <StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,0,90,0"  
                            Visibility="{Binding CountLabelVisible, Converter={StaticResource VisibilityConverter}}">
 <TextBlock Text="Sort By"  />
 <ComboBox Style="{StaticResource ComboBoxStyle1}" Width="100" x:Name="ComboBoxSorting" ItemsSource="{Binding SortBy}" />
   </StackPanel>

My two properties are

    public bool CountLabelVisible { get; set; }

    public bool CountLabelVisibleReverse { get; set; }

Dependency property callback

   private static void ItemsCollectionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs eventArgs)
    {
        var listingUserControl = (obj as ListingUserControl);

        var itemsResult = (eventArgs.NewValue as List<ItemsResult>);
        if (listingUserControl != null && itemsResult != null)
        {
            listingUserControl.CountLabelVisible = itemsResult.Count > 0;
            listingUserControl.CountLabelVisibleReverse =itemsResult.Count <= 0;
        }
    }

Converter code is

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (parameter == null)
            return (bool)value == false ? Visibility.Collapsed : Visibility.Visible;

        return (bool)value ? Visibility.Collapsed : Visibility.Visible;
    }

解决方案

You have made the classic mistake of binding to auto properties that are valid for binding, but don't notify upon change, which means the binding subsystem cannot detect changes and update the binding targets.

To fix this, implement INotifyPropertyChanged on your viewmodel, and then ensure that you notify the property change from the properties.

As an example, I have the following in the base class for my viewmodels:

public abstract class BaseViewModel : INotifyPropertyChanged
{

    /// <summary>
    /// Helper method to set the value of a property and notify if the value has changed.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="newValue">The value to set the property to.</param>
    /// <param name="currentValue">The current value of the property.</param>
    /// <param name="notify">Flag indicating whether there should be notification if the value has changed.</param>
    /// <param name="notifications">The property names to notify that have been changed.</param>
    protected bool SetProperty<T>(ref T newValue, ref T currentValue, bool notify, params string[] notifications)
    {
        if (EqualityComparer<T>.Default.Equals(newValue, currentValue))
            return false;

        currentValue = newValue;
        if (notify && notifications.Length > 0)
            foreach (string propertyName in notifications)
                OnPropertyChanged(propertyName);

        return true;
    }

    /// <summary>
    /// Raises the <see cref="E:PropertyChanged"/> event.
    /// </summary>
    /// <param name="propertyName">The name of the property that changed.</param>
    protected void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    /// <summary>
    /// Occurs when a property value changes.
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

}

then in your regular viewmodel:

public class MyViewModel : BaseViewModel
{
    private bool _countLabelVisible;

    public bool CountLabelVisible
    {
        get { return _countLabelVisible; }
        set { SetProperty(ref value, ref _countLabelVisible, true, "CountLabelVisible", "CountLabelVisibleReverse"); }
    }

    public bool CountLabelVisibleReverse { get { return !_countLabelVisible; }} 
}

This way, when CountLabelVisible gets changed it also notifies on the property CountLabelVisibleReverse, and the property CountLabelVisibleReverse consists of only a getter - because it will always be the inverse of CountLabelVisible.

So that fixes your code the way you have it, but the reality is you don't need to keep the CountLabelVisibleReverse property, instead you could:

  • create an inverse visibility converter as a separate converter
  • create a multi function visibility converter by passing an optional parameter on the binding
  • stack multiple converters, where the output from one converter is piped into the input of the next converter

这篇关于在WPF C#绑定能见度转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆