2010-09-02 126 views
0

我有一个wpf mvvm应用程序。我尝试写入复选框列表控件。
我可以绑定复选框列表元素。
除了这个问题,我想获得所选复选框列表元素值的总和。
我添加了DependencyProperty并将其绑定到视图模型属性。
但是,他们不会互相攻击。WPF MVVM用户控件绑定问题

的CheckBoxList用户控制的Xaml

<ListBox x:Name="ItemsControl" ItemsSource="{Binding}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <CheckBox Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=TwoWay}" 
         Checked="CheckBox_Checked" Unchecked="CheckBox_Checked" /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

的CheckBoxList代码后面

public partial class CheckBoxList : UserControl 
{ 
    public CheckBoxList() 
    { 
     InitializeComponent(); 
    } 

    public static readonly DependencyProperty SelectedCheckBoxItemsValueProperty = 
     DependencyProperty.Register("SelectedCheckBoxItemsValue", typeof(int), typeof(CheckBoxList), 
      new FrameworkPropertyMetadata(
       0, 
       new FrameworkPropertyMetadata(0, OnSelectedItemsChanged)); 

    public int SelectedCheckBoxItemsValue 
    { 
     get { return (int)GetValue(SelectedCheckBoxItemsValueProperty); } 
     set { SetValue(SelectedCheckBoxItemsValueProperty, value); } 
    } 

    private static int GetSelectedCheckBoxItemsValue(DependencyObject obj) 
    { 
     return (int)obj.GetValue(SelectedCheckBoxItemsValueProperty); 
    } 

    private static void OnSelectedItemsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) 
    { 
     CheckBoxList checkboxList = obj as CheckBoxList; 
     ObservableCollection<ISelectableItem> items = checkboxList.DataContext as ObservableCollection<ISelectableItem>; 

     foreach (var item in items) 
     { 
      item.IsSelected = (GetSelectedCheckBoxItemsValue(obj) & item.Value) != 0; 
     } 
    } 

    private void CheckBox_Checked(object sender, RoutedEventArgs e) 
    { 
     CheckBoxList checkboxList = sender as CheckBoxList; 
     ObservableCollection<ISelectableItem> coll = ItemsControl.DataContext as ObservableCollection<ISelectableItem>; 
     if (coll == null) return; 

     int count = 0; 
     foreach (var item in coll) 
     { 
      if (item.IsSelected) 
      { 
       count += item.Value; 
      } 
     } 

     SelectedCheckBoxItemsValue = count; 
    } 
} 

SelectableItem类

public interface ISelectableItem : INotifyPropertyChanged 
{ 
    bool IsSelected { get; set; } 
    string Text { get; set; } 
    int Value { get; set; } 
    string GroupName { get; set; } 
} 

public class SelectableItem : ISelectableItem 
{ .... 

视图模型属性

public int SelectedCheckBoxEnumItemsValue 
    { 
     get 
     { 
      return _selectedCheckBoxEnumItemsValue; 
     } 
     set 
     { 
      _selectedCheckBoxEnumItemsValue = value; 
      NotifyOfPropertyChange("SelectedCheckBoxEnumItemsValue"); 
     } 
    } 

在粘合剂类

 string selectedItemPropertyName = "Selected" + viewModelProperty.Name + "Value"; 
     var property = viewModelProperties.FirstOrDefault(p => p.Name.Contains(selectedItemPropertyName)); 

     if (property != null) 
     { 
      var selectedItemOrValueBinding = new Binding(property.Name) 
      { 
       Mode = property.CanWrite ? BindingMode.TwoWay : BindingMode.OneWay, 
       ValidatesOnDataErrors = Attribute.GetCustomAttributes(property, typeof(ValidationAttribute), true).Any() 
      }; 

      BindingOperations.SetBinding(control, CheckBoxList.SelectedCheckBoxItemsValueProperty, selectedItemOrValueBinding); 
     } 

回答

0

下面的代码解决您的问题..

请注意视图模型的segrgation。

<StackPanel> 
      <TextBlock Text="{Binding Count}"></TextBlock> 
      <ListBox x:Name="ItemsControl" ItemsSource="{Binding CheckList}"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <CheckBox Name="item" Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=TwoWay}" Command="{Binding CheckboxCheckedCommand}" CommandParameter="{Binding IsChecked, ElementName=item}"/> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 

     </StackPanel>  




    public partial class MainWindow : Window 
     { 
      public MainWindow() 
      { 
       InitializeComponent(); 
       DataContext = new MasterViewModel(); 
      } 
     } 




public class MasterViewModel : INotifyPropertyChanged 
{ 
    private List<CheckBoxItem> checkList; 
    private int count; 

    public int Count 
    { 
     get 
     { 
      return count; 
     } 
     set 
     { 
      count = value; 
      OnPropertyChanged("Count"); 
     } 
    } 
    public List<CheckBoxItem> CheckList 
    { 
     get 
     { 
      return checkList; 
     } 
     set 
     { 
      checkList = value; 
      OnPropertyChanged("CheckList"); 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged; 

    public MasterViewModel() 
    { 
     checkList = new List<CheckBoxItem>(); 
     for (int i = 0; i < 5; i++) 
     { 
      CheckBoxItem item = new CheckBoxItem(); 
      item.Text = i.ToString(); 
      item.IsSelected = false; 
      item.CheckboxCheckedCommand = new RelayCommand(new Action<object>(ExecuteCheckCommand)); 
      checkList.Add(item); 
     } 

    } 
    private void ExecuteCheckCommand(object parameter) 
    { 
     if (parameter.GetType() == typeof(bool)) 
     { 
      bool value = bool.Parse(parameter.ToString()); 
      int val = count; 
      if (value) 
      {  
       val++;         
      } 
      else 
      { 
       val--; 
      } 
      Count = val; 
     } 
    } 

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

public class CheckBoxItem : INotifyPropertyChanged 
{ 
    private bool isSelected; 
    private string text; 

    public string Text 
    { 
     get 
     { 
      return text; 
     } 
     set 
     { 
      text = value; 
      OnPropertyChanged("Text"); 
     } 
    } 
    public bool IsSelected 
    { 
     get 
     { 
      return isSelected; 
     } 
     set 
     { 
      isSelected = value; 
      OnPropertyChanged("IsSelected"); 
     } 
    } 

    public ICommand CheckboxCheckedCommand 
    { 
     get; 
     set; 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

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

public class RelayCommand : ICommand 
{ 
    private Action<object> executeCommand; 

    public RelayCommand(Action<object> executeCommand) 
    { 
     this.executeCommand = executeCommand; 
    } 

    public bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     executeCommand(parameter); 
    } 
} 
+0

在我的代码中,你能提出问题出在哪里吗? – pirimoglu 2010-09-03 11:43:51

+0

如果上述解决方案解决了您的问题,请将其标记为答案。 是的,首先尝试为您的控件定义责任。尝试参考MVVM上的文章,他们会提高你对WPF的理解。参考你的代码,我发现很多问题,首先需要创建控制。 – RockWorld 2010-09-04 06:38:25