2012-03-28 87 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