2011-11-08 63 views
5

Tôi có một mục ListView ItemsSource được liên kết với ObservableCollection. Tôi đã thêm một thuộc tính thông qua MVVM để theo dõi ListView.SelectedItem. Một nút đã được thêm vào ListView của tôi (thông qua GridViewColumn.CellTemplate) để tạo ra một nút lệnh hiển thị dữ liệu liên quan đến từng đối tượng trong ObservableCollection của tôi. Vì vậy, danh sách các đối tượng trong ObservableCollection của tôi (ListView cột 1) được hiển thị trong ListView với một nút tương ứng (ListView cột 2).Cách liên kết nút với ListView.SelectedItem

Mã hoạt động tuyệt vời! Vấn đề duy nhất: người dùng phải nhấp vào hàng ListView trước khi nhấp vào nút tương ứng trong danh sách. (Tôi nhận được một ngoại lệ tham chiếu null trên thuộc tính "SelectedFromQueue" của tôi nếu người dùng nhấp vào nút mà không cần nhấp vào hàng ListView trước.)

Tôi muốn thêm mã đặt thuộc tính ListView.SelectedItem khi một nút được nhấp. Vì vậy, nếu người dùng nhấp vào một nút, mã nên cập nhật các thuộc tính ListView.SelectedItem ràng buộc trước khi lệnh MVVM liên quan được thực hiện.

Có ai có mã ví dụ nào về điều này không? Cảm ơn bạn đã giúp đỡ.

XAML của tôi:

<UserControl xmlns:local="clr-namespace:MyApp" 
      x:Class="MyApp.QueueObjectList" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" Height="290" Width="320"> 

    <Grid Width="319"> 
     <GroupBox Header="Queue Class List" HorizontalAlignment="Left" Width="319" BorderBrush="Black" BorderThickness="2"> 
      <ListView ItemsSource="{Binding Path=QueueList}" Name="QueueListView"> 
       <ListView.SelectedItem> 
        <Binding Path="SelectedFromQueue" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"> 
        </Binding>    
       </ListView.SelectedItem> 
       <ListView.View> 
        <GridView> 
         <GridViewColumn Width="140" Header="Queue Name" DisplayMemberBinding="{Binding Name}" /> 
         <GridViewColumn Width="179" Header="Property Information"> 
          <GridViewColumn.CellTemplate> 
           <DataTemplate> 
            <Button Content="Get Property Info" Command="{Binding Path=GetQueueObjProperties}" 
             DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=ListView}}" />      
           </DataTemplate> 
          </GridViewColumn.CellTemplate> 
         </GridViewColumn> 
        </GridView> 
       </ListView.View> 
      </ListView> 
     </GroupBox> 
    </Grid> 
</UserControl> 

My MainWindowViewModel C# Code:

private ObservableCollection<Queue> _QueueList; 
private Queue _selectedFromQueue; 

public ObservableCollection<Queue> QueueList 
{ 
    get { return _QueueList; } 
    set 
    { 
     _QueueList = value; 
     RaisePropertyChanged("QueueList"); 
    } 
} 

public Queue SelectedFromQueue 
{ 
    get { return _selectedFromQueue; } 
    set 
    { 
     _selectedFromQueue= value; 
     RaisePropertyChanged("SelectedFromQueue"); 
    } 
} 

// Constructor 
public MainWindowViewModel() 
{ 
    QueueList = new ObservableCollection<Queue>(); 
    _selectedFromQueue= null; 
} 

public ICommand GetQueueObjProperties 
{ 
    get { return new RelayCommand(GetQueueProperties, CanGetQueueProperties); } 
} 

private bool CanGetQueueProperties() 
{ 
    if (_QueueList.Count > 0) 
    { 
     return true; 
    } 
    return false; 
} 

private void GetQueueProperties() 
{ 
    if (CanGetQueueProperties()) 
    { 
     ResponseMessage.Add("Queue name: " +SelectedFromQueue.Name); 
    } 
} 

Cập nhật: Cảm ơn SLL!

Tôi được thêm vào sau mã XAML của tôi:

  <ListView.Resources> 
       <Style TargetType="{x:Type ListViewItem}"> 
        <EventSetter Event="PreviewGotKeyboardFocus" Handler="SelectCurrentItem"/> 
       </Style> 
      </ListView.Resources> 

Tôi được thêm vào C# phương pháp sau để mã sau:

 protected void SelectCurrentItem(Object sender, KeyboardFocusChangedEventArgs e) 
     { 
      ListViewItem item = (ListViewItem)sender; 
      item.IsSelected = true; 
     } 

Các công trình lớn! Cảm ơn bạn lần nữa vì đã tham khảo!

+1

Tôi đã hỏi những giống trước đây, hãy ra câu hỏi này có lẽ giải pháp được cung cấp bởi Rachel sẽ giúp bạn: WPF: [Kích hoạt SelectedIndex thay đổi trong khi nhấp vào bất kỳ điều khiển trong một khu vực ListBoxItem] (http://stackoverflow.com/questions/6680987/wpf-trigger-selectedindex-changed-whilst-clicking-on-any-control-within -a-listb) – sll

Trả lời

1

Tôi không chắc chắn những gì GetQueueProperties có, nhưng có vẻ như bạn sử dụng SelectedFromQueue để biết mục nào thực thi logic của bạn và lựa chọn trong GUI là thứ yếu.

Nếu đó là trường hợp, không sử dụng SelectedFromQueue nhưng thêm video này vào các Button:

CommandParameter="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType=ListViewItem}}" 

này sẽ cung cấp cho bạn một đối tượng Queue gắn liền với dãy nút bấm như e.Parameter trong SelectedFromQueue.

Nếu bạn làm cần phải thiết lập mục được chọn cho giao diện, vào lúc bắt đầu SelectedFromQueue add:

SelectedFromQueue = (e.Parameter is Queue) ? e.Parameter : null 
+0

Cảm ơn XAMeLi Lưu ý mã mới tôi đã thêm vào bài đăng này. Tôi đã thêm một ListView.Resource mới để truy cập EventSetter cho ListView. Trình xử lý sự kiện liên kết đến một phương thức C# mới trong đoạn mã phía sau.Phương thức C# SelectCurrentItem đặt thuộc tính "IsSelected" thành true khi người dùng di chuột qua bất kỳ hàng nào trong ListView. Bây giờ, người dùng của tôi có thể chỉ cần nhấp vào một nút liên quan đến hàng và truy cập đối tượng tương ứng từ ObservableCollection. – EnLaCucha

Các vấn đề liên quan