2013-07-31 2 views
3
나는 다음과 같은 요구 사항이

에있는 모든 항목 :WPF - MVVM : 확인하는 방법/선택을 취소 ListView를

  1. 창은 여러 항목과 ListView 표시됩니다.
  2. 사용자는 항목을 선택 (확인란) 할 수 있어야합니다. a) 하나의 항목 인 경우 모든 항목을 선택 해제하고 비활성화해야합니다. b) 체크 된 항목을 선택하지 않으면 모든 항목이 활성화되어야합니다.

지금부터는 다음과 같은 불완전한 코드가 있습니다.

MainWindow를 XAML : ListView에 대한

<Window x:Class="WpfApplication4.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="520.149" Width="732.463"> 
    <Window.Resources> 
     <ResourceDictionary Source="MainWindowResource.xaml" /> 
    </Window.Resources> 

    <Grid> 
    <ListView x:Name="myListBox" ItemTemplate="{StaticResource OfferingTemplate}"> 
      <ListView.ItemsPanel> 
       <ItemsPanelTemplate> 
        <UniformGrid Columns="3" VerticalAlignment="Top"/> 
       </ItemsPanelTemplate> 
      </ListView.ItemsPanel> 
     </ListView> 
    </Grid> 
</Window> 

DataTemplete :

<DataTemplate x:Key="OfferingTemplate"> 
    <StackPanel> 
     <Grid IsEnabled="{Binding IsEnabled}"> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="8"></ColumnDefinition> 
       <ColumnDefinition Width="120"></ColumnDefinition> 
      </Grid.ColumnDefinitions> 
      <Grid.RowDefinitions> 
       <RowDefinition Height="40"></RowDefinition> 
       <RowDefinition Height="50"></RowDefinition> 
       <RowDefinition Height="30"></RowDefinition> 
      </Grid.RowDefinitions> 
      <Rectangle Grid.Column="0" Grid.RowSpan="3" Fill="#F4CA16" /> 
      <Label 
       Grid.Column="1" 
       Grid.Row="0" 
       Content="{Binding Title}" 
       FontSize="18" FontWeight="Bold" 
       Margin="0,0,0,0" /> 
      <TextBlock 
       Grid.Column="1" 
       Grid.Row="1" 
       FontSize="10" 
       Text="{Binding Description}" 
       Foreground="Black" 
       TextWrapping="WrapWithOverflow" 
       Margin="5,0,0,0" /> 
      <CheckBox 
       Grid.Column="1" 
       Grid.Row="2" 
       FontSize="14" 
       IsChecked="{Binding IsSelected}" 
       VerticalAlignment="Bottom" 
       Margin="5,0,0,0"> 

       <TextBlock Text="Select" Margin="0,-2,0,0"/> 
      </CheckBox> 
     </Grid> 
    </StackPanel> 
</DataTemplate> 

모델 :

class MyModel 
{ 
    public string Title { get; set; } 
    public string Description { get; set; } 
    public bool IsSelected { get; set; } 
    public bool IsEnabled { get; set; } 
} 

의 ViewModel :

class MyViewModel : INotifyPropertyChanged 
{ 
    private MyModel offering; 

    public MyViewModel() 
    { 
     offering = new MyModel(); 
    } 

    public int ID { get; set; } 
    public string Title 
    { 
     get { return offering.Title; } 
     set 
     { 
      offering.Title = value; 
      RaisePropertyChanged("Title"); 
     } 
    } 
    public string Description 
    { 
     get { return offering.Description; } 
     set 
     { 
      offering.Description = value; 
      RaisePropertyChanged("Description"); 
     } 
    } 
    public bool IsSelected 
    { 
     get { return offering.IsSelected; } 
     set 
     { 
      offering.IsSelected = value; 
      RaisePropertyChanged("IsSelected"); 
     } 
    } 
    public bool IsEnabled 
    { 
     get { return offering.IsEnabled; } 
     set 
     { 
      offering.IsEnabled = value; 
      RaisePropertyChanged("IsEnabled"); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

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

목록에 'ItemsSource'가 연결되어 있습니까? 이 경우 소스에 항목을 추가 한 다음 속성을 변경하면 CheckBox 변경된 이벤트를 수신 할 수 있어야합니다. – Default

+1

"사용자가 어떤 항목을 체크 할 수 있어야한다) a) 하나의 항목 인 경우, 모든 항목을 체크하지 않고 비활성화해야한다. b) 체크 된 항목이 선택되어 있지 않으면, 모든 항목이 선택되지 않아야한다. 활성화되었습니다. " 나는 당신이 RadioButton을 설명한다고 생각합니다. – Shoe

+0

@ 짐 거의 차이가 있습니다. 체크 박스 중 하나를 선택하면 나머지는 ** 비활성화 **되어야합니다. 따라서 체크 박스의 선택을 해제해야만 다른 것을 선택할 수 있습니다. 그 이유는 모르겠다. 나는 또한 라디오 버튼을 가지고 갔다. – Default

답변

4

이 흥미로운 질문이다. 원하는 동작이 목록의 모든 항목에 적용되므로이 논리는 목록 클래스 수준에 있어야합니다. MyViewModel 클래스가 좋습니다. 목록 클래스와 XAML에 논리를 추가해야하지만 Prism 덕분에 매우 쉽습니다.

(안 게시물에 표시) 목록 클래스를 포함합니다 :

public ObservableCollection<MyViewModel> MyItems { get; set; } //Binding to ItemsSource 

    private ICommand _selectCommand; 

    public ICommand SelectCommand 
    { 
     get { return _selectCommand ?? (_selectCommand = new DelegateCommand<MyViewModel>(DoSelect)); } 
    } 

    private void DoSelect(MyViewModel myViewModel) 
    { 
     foreach(var item in MyItems) 
      if (item != myViewModel) 
      { 
       item.IsSelected = false; 
       item.IsEnabled = false; 
      } 
    } 

    private ICommand _unselectCommand; 

    public ICommand UnselectCommand 
    { 
     get { return _unselectCommand ?? (_unselectCommand = new DelegateCommand<MyViewModel>(DoUnselect)); } 
    } 

    private void DoUnselect(MyViewModel myViewModel) 
    { 
     foreach (var item in MyItems) 
      if (item != myViewModel) 
      { 
       item.IsEnabled = true; 
      } 
    } 

이 두 명령, 선택 하나 선택 해제에 대한 다른있다. 마법 XAML에 :

 <ListView ItemsSource="{Binding Path=MyItems}" x:Name="listView"> 
      <ListView.ItemTemplate> 
       <DataTemplate> 
        <CheckBox IsChecked="{Binding Path=IsSelected}" IsEnabled="{Binding Path=IsEnabled}"> 
         <i:Interaction.Triggers> 
          <i:EventTrigger EventName="Checked"> 
           <i:InvokeCommandAction Command="{Binding ElementName=listView, Path=DataContext.SelectCommand}" 
                 CommandParameter="{Binding}"/> 
          </i:EventTrigger> 
          <i:EventTrigger EventName="Unchecked"> 
           <i:InvokeCommandAction Command="{Binding ElementName=listView, Path=DataContext.UnselectCommand}" 
                 CommandParameter="{Binding}"/> 
          </i:EventTrigger> 
         </i:Interaction.Triggers> 
        </CheckBox> 
       </DataTemplate> 
      </ListView.ItemTemplate> 
     </ListView> 

프리즘의 트리거를 사용하여, 당신은 당신의 목록보기 모델의 명령 체크 박스의 위탁 수하물과 이벤트를 매핑하고 매개 변수로 항목보기 모델을 통과 할 수 있습니다.

완벽하게 작동하지만 설정 항목의 IsSelected는 별개입니다. CheckBox를 선택하면 뒤에있는 항목이 DataBinding을 통해 true로 설정되지만 다른 모든 항목은 상위 뷰 모델을 통해 설정됩니다. 귀하의 게시물이 모두 귀하의 요구 사항이라면, IsChecked 바인딩을 제거하고 목록보기 모델 내에 IsSelected를 설정하는 논리를 두어 클론하고 쉽게 테스트 코드를 작성할 수 있습니다.

+0

완벽 ... 빌 고마워요. –