4

カウントに基づいてコールバックが発生したときに、コレクションタイプの依存関係プロパティがあり、画面上のいくつかのコントロールの可視性を設定する必要があります。

ただし、コントロールは常に折りたたまれたままです。コードに従って、1つのコントロールが常に表示されたままになります。

XAMLバインディングは

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

私の2つのプロパティは

    public bool CountLabelVisible { get; set; }

    public bool CountLabelVisibleReverse { get; set; }

依存関係プロパティのコールバック

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

コンバーターコードは

 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;
    }
4

4 に答える 4

5

バインドに有効な自動プロパティにバインドするという古典的な間違いを犯しましたが、変更時に通知しません。つまり、バインドサブシステムは変更を検出してバインドターゲットを更新できません。

これを修正するには、ビューモデルにINotifyPropertyChangedを実装してから、プロパティからプロパティの変更を通知するようにします。

例として、ビューモデルの基本クラスに次のものがあります。

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;

}

次に、通常のビューモデルで:

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

このように、CountLabelVisible変更されると、プロパティについても通知されますCountLabelVisibleReverse。プロパティCountLabelVisibleReverseは、常に。の逆であるため、ゲッターのみで構成されますCountLabelVisible

これにより、コードは現在の方法で修正されますが、実際には、CountLabelVisibleReverseプロパティを保持する必要はありません。代わりに、次のことができます。

  • 別のコンバーターとして逆可視性コンバーターを作成する
  • バインディングにオプションのパラメーターを渡して、多機能の可視性コンバーターを作成します
  • 複数のコンバーターをスタックします。1つのコンバーターからの出力が次のコンバーターの入力にパイプされます
于 2012-12-05T10:13:32.577 に答える
0

変更されたときにビューに通知するためにバインドするブールプロパティはありますか?このようなSth:

private bool countLabelVisible;
public bool CountLabelVisible
{
  get
  {
    return countLabelVisible;
  }
  set
  {
   if (countLabelVisible != value)
   {
      countLabelVisible = value;
      RaisePropertyChanged(() => CountLabelVisible);
   }
}

ラムダを使用したRaisePropertyChangedメソッドを使用できるようにするには、viewodelがNotificationObjectから継承する必要があります

于 2012-12-05T10:09:50.877 に答える
0

変更を通知する必要があります。

public event PropertyChangedEventHandler PropertyChanged;
private bool _countLabelVisible = false;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}


public bool CountLabelVisible 
{ 
    get
    {
        return _countLabelVisible;
    }
    set
    {
        _countLabelVisible = value;
        RaisePropertyChanged("CountLabelVisible");
    }
}

バインディングの「フレームワーク」には、バインディングを更新する必要があることを通知する必要があります。これが、Raise...の目的です。これはかなり速くて汚い(そしてテストされていない)が、あなたがする必要があることを示すはずです。

于 2012-12-05T10:10:58.720 に答える
-1

ブール値から可視性へのコンバータークラス

    public class BoolToVisibilityConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return (bool)value ? Visibility.Visible : Visibility.Hidden;
            }

            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

Xaml可視性コンバータークラスの使用を示すために、以下で説明する変更。ここでは、可視性を示すためにグループボックスが使用されています。ラジオボタン選択の変更時に、グループボックスが表示/非表示になります。

 <Page x:Class="WpfApplication.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:vm="clr-namespace:WpfApplication" HorizontalAlignment="Left" VerticalAlignment="Top"
            Title="Customer"  Loaded="Page_Loaded">
        <Page.Resources>
            <vm:BoolToVisibilityConverter x:Key="converter" 
    </Page.Resources>
<RadioButton Grid.Column="0" x:Name="rdbCustomerDetail"  
    Content="Show Customer" 
    IsChecked="{Binding IsCustomerDetailChecked,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            <GroupBox Header="Customer Details" Visibility="{Binding 

            Path=IsCustomerDetailChecked, 
            UpdateSourceTrigger=PropertyChanged, 
            Converter={StaticResource  converter}}">
    </GroupBox>

ViewModelでは、xamlの可視性の変更を取得するのはあなただけではなくinvokepropertychangeを使用します。

private Boolean isCustomerDetailChecked = false;
    public Boolean IsCustomerDetailChecked
    {
        get
        {
            return isCustomerDetailChecked;
        }
        set
        {
            isCustomerDetailChecked = value;
            InvokePropertyChanged("IsCustomerDetailChecked");
        }
    }
于 2014-05-27T09:25:00.980 に答える