2013-10-07 40 views
1

在列表框中,我有複選框和TextBlock中的項目我想更新計數器,顯示當前有多少人被檢查。 簡單的情況,但我刷新計數器的綁定有問題。如何刷新多重綁定

我的XAML:

<Window x:Class="ListboxWithCounting.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:vm="clr-namespace:ListboxWithCounting" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.DataContext> 
     <vm:MyViewModel /> 
    </Window.DataContext> 
    <Window.Resources> 
     <DataTemplate x:Key="CheckBoxListItem"> 
      <Border x:Name="CheckBoxItemElement" 
        Background="Transparent" 
        Padding="0,2,0,2"> 
       <CheckBox Content="{Binding Name}" 
          IsChecked="{Binding Path=IsChecked,Mode=TwoWay, 
        UpdateSourceTrigger=PropertyChanged}"/> 
      </Border> 
     </DataTemplate> 
    </Window.Resources> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="*" /> 
      <ColumnDefinition Width="*"/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="*" /> 
     </Grid.RowDefinitions> 

     <TextBlock Grid.Column="1"> 
      <TextBlock.Text> 
       <MultiBinding StringFormat="Items checked: {0} of {1}"> 
        <Binding Path="ColumnsChecked" /> 
        <Binding Path="ColumnsCount" /> 
       </MultiBinding> 
      </TextBlock.Text> 
     </TextBlock> 

     <ListBox ItemTemplate="{StaticResource CheckBoxListItem}" 
         x:Name="Columns" 
         ItemsSource="{Binding Columns}" /> 
    </Grid> 
</Window> 

我的視圖模型和單個項目:

public class Item : INotifyPropertyChanged 
    { 
     public string Name { set; get; } 

     private bool isChecked; 
     public bool IsChecked 
     { 
      get 
      { 
       return isChecked; 
      } 
      set 
      { 
       isChecked = value; 
       PropertyChanged(this, new PropertyChangedEventArgs("IsChecked")); 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    } 

    public class MyViewModel 
    { 
     public int ColumnsCount 
     { 
      get 
      { 
       return Columns.Count; 
      } 
     } 

     public int ColumnsChecked 
     { 
      get 
      { 
       return Columns.Where(x => x.IsChecked).Count(); 
      } 
     } 

     public List<Item> Columns 
     { 
      get 
      { 
       var data = new List<Item>() 
       { 
        new Item(){ Name = "Item1", IsChecked=true }, 
        new Item(){ Name = "Item2" }, 
        new Item(){ Name = "Item3" } 
       }; 

       data.ForEach(x => x.PropertyChanged += (s, e) => { }); 

       return data; 
      } 
     } 
    } 

我怎樣才能觸發multibinding當每個並在列表狀態每一個複選框被改變了嗎?

[更新]

由於slugster,工作代碼:

public class Item : INotifyPropertyChanged 
    { 
     public string Name { set; get; } 

     private bool isChecked; 
     public bool IsChecked 
     { 
      get 
      { 
       return isChecked; 
      } 
      set 
      { 
       if (isChecked != value) 
       { 
        isChecked = value; 
        PropertyChanged(this, new PropertyChangedEventArgs("IsChecked")); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    } 

    public class MyViewModel : INotifyPropertyChanged 
    { 
     public int ColumnsCount 
     { 
      get 
      { 
       return Columns.Count; 
      } 
     } 

     public int ColumnsChecked 
     { 
      get 
      { 
       return Columns.Where(x => x.IsChecked).Count(); 
      } 
     } 

     private List<Item> columns; 
     public List<Item> Columns 
     { 
      get 
      { 
       if (columns == null) 
       { 
        columns = new List<Item>() 
        { 
         new Item(){ Name = "Item1", IsChecked=true }, 
         new Item(){ Name = "Item2" }, 
         new Item(){ Name = "Item3" } 
        }; 
       } 

       columns.ForEach(x => 
       { 
        x.PropertyChanged -= x_PropertyChanged; 
        x.PropertyChanged += x_PropertyChanged; 
       }); 

       return columns; 
      } 
     } 

     void x_PropertyChanged(object sender, PropertyChangedEventArgs e) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("ColumnsChecked")); 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    } 

回答

2

您的視圖模型也需要實現INotifyPropertyChanged,這樣的結合可以知道在列表項屬性修改。

說實話,我不能告訴你我的頭頂是否僅僅通知一個屬性會導致整個多重綁定被評估(在任何情況下你都可以快速找到),但是你可能想要通知在任何其他綁定的情況下,這兩個屬性。

public class MyViewModel : INotifyPropertyChanged 
{ 

    [...snip...] 

    public List<Item> Columns 
    { 
     get 
     { 
      var data = new List<Item>() 
      { 
       new Item(){ Name = "Item1", IsChecked=true }, 
       new Item(){ Name = "Item2" }, 
       new Item(){ Name = "Item3" } 
      }; 

      data.ForEach(x => x.PropertyChanged += (s, e) => {  
                   OnPropertyChanged("ColumnsCount"); 
                   OnPropertyChanged("ColumnsChecked"); 
                  }); 

      return data; 
     } 
    } 

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

    public event PropertyChangedEventHandler PropertyChanged; 

} 
+0

謝謝。我需要稍微修改代碼,所以我編輯了我以前的帖子。 – lszk

+2

我可以確認在多重綁定中對任何綁定進行通知的修改將導致多重綁定重新評估。 – Gusdor