2010-04-10 24 views
14

Çoklu seçim etkinleştirilmiş bir veri kılavuzum var. Seçimi viewmodel'de değiştirmem gerek. Ancak, SelectedItems özelliği salt okunur ve doğrudan viewmodel'deki bir özellik ile ilişkilendirilemez. Peki seçimin değiştiği görüşüne nasıl işaret edebilirim?WPF DataGrid multiselect bağlama

+0

Ayrıca bkz http://stackoverflow.com/questions/1579700/wpf-toolkit-datagrid-multi-select-how-to-get-selecteditems-out –

cevap

6

ben çok DataGrid ile çalıştı değil, ama ListView için çalışan bir tekniktir bireysel ListViewItem ait IsSelected özelliğine bağlamaktır. Listenizdeki her nesne için bunu true olarak ayarlayın ve ardından seçilecektir.

Belki DataGrid bir satır temsil nesne aynı zamanda bir IsSelected özelliğine sahiptir ve aynı zamanda bu şekilde kullanılabilir?

17

Andy doğrudur. DataGridRow.IsSelected, ViewModel'in seçimini denetlemek için veriye bağlanan Bağımlılık Özelliğidir. Aşağıdaki örnek kod, bu gösterir:

<Window x:Class="DataGridMultiSelectSample.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:tk="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit" 
    Title="Window1" Height="300" Width="300"> 
    <StackPanel> 
     <tk:DataGrid AutoGenerateColumns="False" ItemsSource="{Binding}" EnableRowVirtualization="False"> 
      <tk:DataGrid.Columns> 
       <tk:DataGridTextColumn Header="Value" Binding="{Binding Value}" /> 
      </tk:DataGrid.Columns> 
      <tk:DataGrid.RowStyle> 
       <Style TargetType="tk:DataGridRow"> 
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" /> 
       </Style> 
      </tk:DataGrid.RowStyle> 
     </tk:DataGrid> 
     <Button Content="Select Even" Click="Even_Click" /> 
     <Button Content="Select Odd" Click="Odd_Click" /> 
    </StackPanel> 
</Window> 

using System.ComponentModel; 
using System.Windows; 

namespace DataGridMultiSelectSample 
{ 
    public partial class Window1 
    { 
     public Window1() 
     { 
      InitializeComponent(); 
      DataContext = new[] 
           { 
            new MyViewModel {Value = "Able"}, 
            new MyViewModel {Value = "Baker"}, 
            new MyViewModel {Value = "Charlie"}, 
            new MyViewModel {Value = "Dog"}, 
            new MyViewModel {Value = "Fox"}, 
           }; 
     } 

     private void Even_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[]) DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i%2 == 0; 
     } 

     private void Odd_Click(object sender, RoutedEventArgs e) 
     { 
      var array = (MyViewModel[])DataContext; 
      for (int i = 0; i < array.Length; ++i) 
       array[i].IsSelected = i % 2 == 1; 
     } 
    } 

    public class MyViewModel : INotifyPropertyChanged 
    { 
     public string Value { get; set; } 

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

     public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

DataGrid öğesinin üzerinde EnableRowVirtualisation="False" ayarlamayı unutmayın, başka IsSelected bağlamaları dışında tutulmuş düşme riski var.

+0

mükemmeldir. Ve örnek kod için teşekkürler - güzelce gösterir. –

+0

Teşekkürler. Umarım, 'EnableRowVirtualisation = "False" 'ı ekleyerek eklemenize izin vermezsiniz, çünkü o olmadan, bağlanmanın yeni satırlarda olmadığı bir hata vardır. –

3

Çocuklar yardımlarınız için teşekkürler. Benim problemim çözüldü. Problemin yeni WPF geliştiricileri için oldukça yaygın olduğunu düşünüyorum, bu yüzden bir başkasının aynı türden sorunlara girmesi durumunda, daha fazla ayrıntıda çözümümün yanı sıra problemimi de yeniden ifade edeceğim.

Sorun: Ses dosyaları için çoklu seçim etkin bir veri kılavuzum var. Kılavuzda birden çok sütun başlığı var. Kullanıcı birkaç satırı çok seçebilir. Oynat düğmesini tıklattığında, ses dosyaları sütun başlıklarından birinin sırasına göre oynatılır (sütun A). Oynatma başladığında, çoklu seçim temizlenir ve sadece o anda çalınan dosya vurgulanır. Tüm dosyalar için oynatma bittiğinde, çoklu seçim yeniden görüntülenir. İzleme, viewmodel'de yapılır. Gördüğünüz gibi, burada iki sorun var: 1) o anda çalınan dosyayı viewmodel'den nasıl seçeceğiniz ve 2) izleme modunun bittiği görünüm modunun nasıl görüntüleneceği ve çoklu seçimi yeniden görüntüleyeceğiniz.

Çözüm: İlk sorunu çözmek için, şu anda çalınan dosyayı seçmek üzere görünümün SelectedIndex özelliğine bağlı olan viewmodel'de bir özellik oluşturdum. İkinci problemi çözmek için, oynatımın bittiğini göstermek üzere görünüm modelinde bir boolean özelliği oluşturdum. Görünümün arkasındaki kodda, boolean özelliğinin PropertyChanged olayına abone oldum. Olay işleyicisinde, görünümün SelectedItems özelliği kaydedilmiş çoklu seçimden yeniden oluşturulur (SelectedItems'in içeriği bir listeye kaydedilir ve oynatma başladığında SelectedItems temizlenmiştir). İlk önce, SelectedItems'i yeniden oluşturmada sorun yaşadım. Sorunun ortaya çıkması, yeniden oluşturmanın ikinci bir iş parçacığıyla başlatılmasından kaynaklanıyordu. WPF buna izin vermiyor. Bunun çözümü, ana iş parçasının işi yapmasına izin vermek için Dispatcher.Invoke() yöntemini kullanmaktır. Bu deneyimli geliştiriciler için çok basit bir sorun olabilir, ancak yeni başlayanlar için, küçük bir meydan okumadır. Neyse, farklı insanlardan çok yardım.

2

Herhangi bir MultiSelector türetilmiş sınıfında SelectedItems öğesini kullanın ve IList uygulamasında Add, Remove, Clear yöntemlerini kullanın.

Selamlar, Robin