2012-03-28 91 views
0

我想实现一个复选框,其功能为全选/全选复选框,但我遇到了绑定的一些问题。我对XAML和WPF并不是很陌生,所以对我来说,为什么我的代码无法正常工作。我希望你能帮忙。这是我在做什么:绑定与复选框(全选)

首先,我使用MVVMLight和event-to-command标签。

我的观点被称为SetupView.xaml和我的视图模型被称为SetupViewModel.cs

public class SetupViewModel : ViewModelBase 
{ 
    private List<FilterOptions> m_informationToShow; 
    private FilterOptions m_currentSelection; 

    public List<FilterOptions> InformationToShow 
    { 
     get { return m_informationToShow; } 
     set 
     { 
      m_informationToShow = value; 
      RaisePropertyChanged("InformationToShow"); 
      RaisePropertyChanged("InformationToShowCount"); 
     } 
    } 

    public FilterOptions CurrentSelection 
    { 
     get { return m_currentSelection; } 
     set 
     { 
      m_currentSelection = value; 
      RaisePropertyChanged("CurrentSelection"); 
     } 
    } 
} 

的FilterOptions对象是我的模型对象。因为你会需要一些它是要了解这个问题,这里展示的一部分,你需要了解的问题:

public class FilterOptions 
{ 
    private string m_projectName; 

    private BugsFilter m_bugsFilter; 
    private BuildsFilter m_buildsFilter; 
    private ChangeSetsFilter m_changeSetsFilter; 
    private ProgressInfoFilter m_progressInfoFilter; 
    private RisksFilter m_risksFilter; 

    private bool m_projectHealthFilter; 

    public bool AllFilterValues 
    { 
     get 
     { 
      if (m_bugsFilter.AtLeastOneFieldEnabled() || 
       m_buildsFilter.AtLeastOneFieldEnabled() || 
       m_changeSetsFilter.AtLeastOneFieldEnabled() || 
       m_progressInfoFilter.AtLeastOneFieldEnabled() || 
       m_risksFilter.AtLeastOneFieldEnabled() || 
       m_projectHealthFilter 
       ) 
      { 
       return true; 
      } 
      else 
      { 
       return false; 
      } 
     } 
     set 
     { 
      if (value == false) 
      { 
       m_bugsFilter.NoInformation(); 
       m_buildsFilter.NoInformation(); 
       m_changeSetsFilter.NoInformation(); 
       m_progressInfoFilter.NoInformation(); 
       m_risksFilter.NoInformation(); 
       m_projectHealthFilter = false; 
      } 
      else 
      { 
       m_bugsFilter.CompleteInformation(); 
       m_buildsFilter.CompleteInformation(); 
       m_changeSetsFilter.CompleteInformation(); 
       m_progressInfoFilter.CompleteInformation(); 
       m_risksFilter.CompleteInformation(); 
       m_projectHealthFilter = true; 
      } 
     } 
    } 

我将与我的观点出发:

<UserControl.Resources> 
    <viewModels:SetupViewModel x:Key="thisViewModel"></viewModels:SetupViewModel> 

    <DataTemplate x:Key="ProjectEntryTemplate"> 
     <Border Margin="75,20,5,0"> 
      <CheckBox Name="naam" Content="{Binding ProjectName}" 
         FontFamily="Segoe UI" 
         FontWeight="Light" 
         FontSize="24" 
         IsChecked="{Binding AllFilterValues}" 
         DataContext="{Binding}"> 
       <i:Interaction.Triggers> 
        <i:EventTrigger EventName="Checked"> 
         <mvvm:EventToCommand Command="{Binding ProjectListItemCheckedChanged, Source={StaticResource thisViewModel}}" 
              PassEventArgsToCommand="True"/> 
        </i:EventTrigger> 
        <i:EventTrigger EventName="Unchecked"> 
         <mvvm:EventToCommand Command="{Binding ProjectListItemCheckedChanged, Source={StaticResource thisViewModel}}" 
              PassEventArgsToCommand="True"/> 
        </i:EventTrigger> 
       </i:Interaction.Triggers> 
      </CheckBox> 
     </Border> 
    </DataTemplate> 
</UserControl.Resources> 

正如你所看到的我有我使用一个列表框其中一个DataTemplate:

<ListBox ItemsSource="{Binding InformationToShow}" 
          ItemTemplate="{StaticResource ProjectEntryTemplate}" 
          SelectedIndex="0" 
          BorderThickness="0"> 
        <i:Interaction.Triggers> 
         <i:EventTrigger EventName="SelectionChanged"> 
          <mvvm:EventToCommand Command="{Binding SelectionListboxChanged}" 
                PassEventArgsToCommand="True"/> 
         </i:EventTrigger> 
        </i:Interaction.Triggers> 
       </ListBox> 

除了来自的是,我在同一个窗口,在右侧的另一格,很多复选框。它们都对应于FilterOptions对象的给定过滤器。这是我在做什么,我认为:

<StackPanel Orientation="Vertical" 
           Margin="0,5,0,5"> 
         <CheckBox Name="activeBugs" Content="Active bugs" 
            FontFamily="Segoe UI" 
            FontWeight="Light" 
            FontSize="22" 
            IsChecked="{Binding CurrentSelection.BugsFilter.ActiveBugs}"> 
         </CheckBox> 

         <CheckBox Name="resolvedBugs" Content="Resolved bugs" 
            FontFamily="Segoe UI" 
            FontWeight="Light" 
            FontSize="22" 
            IsChecked="{Binding CurrentSelection.BugsFilter.ResolvedBugs}"/> 
         <CheckBox Name="bugTrend" Content="Bug trend" 
            FontFamily="Segoe UI" 
            FontWeight="Light" 
            FontSize="22" 
            IsChecked="{Binding CurrentSelection.BugsFilter.BugTrend}"/> 
        </StackPanel> 

最后但并非最不重要的,这是我在我的视图模型的命令功能:

RelayCommand m_selectionChanged; 
    public ICommand SelectionListboxChanged 
    { 
     get 
     { 
      if (m_selectionChanged == null) 
       m_selectionChanged = new RelayCommand(param => SelectionListboxChangedExec(param), param => true); 

      return m_selectionChanged; 
     } 
    } 

    private void SelectionListboxChangedExec(object param) 
    { 
     SelectionChangedEventArgs e = (SelectionChangedEventArgs)param; 
     ListBox b = (ListBox)e.Source; 
     CurrentSelection = (FilterOptions)b.SelectedItem; 
    } 

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 

    RelayCommand m_projectCheckedChanged; 
    public ICommand ProjectListItemCheckedChanged 
    { 
     get 
     { 
      if (m_projectCheckedChanged == null) 
       m_projectCheckedChanged = new RelayCommand(param => ProjectListItemCheckedChangedExec(param), param => true); 

      return m_projectCheckedChanged; 
     } 
    } 

    private void ProjectListItemCheckedChangedExec(object param) 
    { 
     RoutedEventArgs e = (RoutedEventArgs)param; 
     CheckBox checkBox = (CheckBox)e.Source; 
     FilterOptions dataContext = (FilterOptions)checkBox.DataContext; 

     if ((bool)checkBox.IsChecked) 
      dataContext.AllFilterValues = true; 
     else 
     { 
      dataContext.AllFilterValues = false; 
     } 

     //var expression = checkBox.GetBindingExpression(ToggleButton.IsCheckedProperty); 
     //expression.UpdateSource(); 
    } 

我真的不能发现问题。有没有人可以帮助我? 您的帮助将非常感谢!

谢谢大家提前!

回答

0

为什么你必须用命令做到这一点?将复选框绑定到内部通知父类ViewModelBindingOption类,此通知实际上不属于视图,而是属于视图模型。

ViewModel不应该知道该视图使用CheckBox。

,这样你们应该做的事情有个别选项有一个通知IsSelected属性绑定到CheckBox ES,提供​​他们每个人父ViewModel的引用,当电流IsSelected变更通知父。在View中执行此操作,尽管您可以找到很多方法来实现它,但您不应该这么做,MVVM将视图任务与ViewModel任务分开。

这顺便也为您提供了“全选”,“取消选择所有”或“反选”等

+0

即使我不使用的命令,它仍然没有工作控制。 我并正确绑定的一切,但问题仍然存在... – 2012-04-02 12:48:29

+0

嗯,我觉得必须有一个错误的原因: 私人无效SelectionListboxChangedExec(对象PARAM) { SelectionChangedEventArgs E =(SelectionChangedEventArgs)参数; ListBox b =(ListBox)e。资源; CurrentSelection =(FilterOptions)b.SelectedItem; CurrentSelection.ProjectName =“ba”; RaisePropertyChanged(“CurrentSelection”); } } 只是工作,但当我绑定它不更新.... – 2012-04-02 13:27:18

+0

@JoshMulholland,我不完全明白什么是不更新,请扩展您的问题与代码和评论它什么不工作,请在这里评论,以便我的更新通知您。谢谢。 – Shimmy 2012-04-02 21:21:01