2015-02-11 2 views
1

У меня есть приложение с несколькими элементами управления элементами (древовидные и другие), которые содержат шаблон элемента с флажком внутри. Это установленное флажком состояние привязано к свойству IsChecked модели представления элемента. Это работает правильно, когда вы нажимаете на этот флажок, но невозможно проверить/снять флажок с клавиатуры (я считаю, что это связано с тем, что флажок сам по себе никогда не фокусируется).Поведение WPF для проверки/снятия флажка в элементе списка

Мне нравится решение, предложенное DLeh здесь: https://stackoverflow.com/a/24327765/352826, но я хотел бы улучшить: вместо того, чтобы поведение вызывало команду на базовой модели представления (vm, которая содержит список элементов), я хотел бы, чтобы поведение для прямого действия на свойство IsChecked этого элемента. Моя проблема в том, что я не знаю, как изменить поведение или как установить привязку на нем, чтобы поведение могло иметь доступ к свойству IsChecked. Таким образом, вместо того, чтобы следующее:

<DataGrid> 
    <i:Interaction.Behaviors> 
     <shared:ToggleSelectOnSpace ToggleSelectCommand="{Binding Data.ToggleSelectParticipantCommand, Source={StaticResource BindingProxy}}" /> 
    </i:Interaction.Behaviors> 
... 
</DataGrid> 

я бы что-то вроде этого:

<DataGrid> 
    <i:Interaction.Behaviors> 
     <shared:ToggleSelectOnSpace ItemsIsSelectedProperty="{Binding IsChecked}" /> 
    </i:Interaction.Behaviors> 
... 
</DataGrid> 

Update Я должен добавить, что моя текущая реализация использует событие PreviewKeyUp в ItemsControl и следующая кода позади реализации. Проблема с этим подходом заключается в том, что у меня есть этот код во многих файлах с кодом, поэтому есть много дублирования. Моя цель - заменить это поведением.

private void TreeView_OnPreviewKeyUp(object sender, KeyEventArgs e) 
{ 
    if (e.Key == Key.Space) 
    { 
     var tree = (TreeView) sender; 
     var item = tree.SelectedItem as IsSelectedViewModelBase; 
     if (item != null) 
     { 
      item.IsSelected = !item.IsSelected; 
      e.Handled = true; 
     } 
    } 
} 

Update 2 Это шаблон элемента и флажок не установлен, при нажатии на пробел с выбранного элемента.

<DataTemplate DataType="{x:Type viewModels:ItemViewModel}" > 
    <StackPanel Orientation="Horizontal" > 
     <CheckBox Focusable="False" IsChecked="{Binding IsSelected}" VerticalAlignment="Center" /> 
     <StackPanel Margin="2"> 
      <TextBlock Text="{Binding Username}" FontWeight="Bold" /> 
      <TextBlock Text="{Binding FullName}" /> 
     </StackPanel> 
    </StackPanel> 
</DataTemplate> 
+0

что делает логика выглядеть в вашей команде? – DLeh

+0

См. Обновление в вопросе –

+0

@Francesc Мне удалось создать шаблон элемента, в котором был элемент управления «CheckBox», который мог получать фокус и переключаться с помощью пробела, поэтому я не уверен, почему это не было для вас. Что-то еще предотвращает фокус клавиатуры, например, настройку свойства далее вверх по дереву элементов? Если вы хотите, я могу опубликовать свой пример кода. –

ответ

0

Не ответ на заданный вопрос сам по себе, но следующий будет показать, что это возможно для флажка в элементе списка, чтобы получить фокус клавиатуры.

Я создал новый проект WPF с использованием шаблона Visual Studio по умолчанию. Это создает одно окно под названием «MainWindow». Вот содержимое XAML и кода для этого окна.

MainWindow.xaml.cs

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Windows; 

namespace WpfApplication1 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 

      Thingies = new List<Thingy> 
      { 
       new Thingy { Name = "abc", IsChecked = false }, 
       new Thingy { Name = "def", IsChecked = true }, 
       new Thingy { Name = "ghi", IsChecked = false }, 
       new Thingy { Name = "jkl", IsChecked = true }, 
       new Thingy { Name = "mno", IsChecked = false }, 
      }.ToArray(); 

      DataContext = this; 
     } 

     public Thingy[] Thingies { get; private set; } 

     public class Thingy : INotifyPropertyChanged 
     { 
      public string Name { get; set; } 

      public bool IsChecked 
      { 
       get 
       { 
        return _isChecked; 
       } 
       set 
       { 
        if (_isChecked != value) 
        { 
         _isChecked = value; 
         if (PropertyChanged != null) 
         { 
          PropertyChanged(this, 
           new PropertyChangedEventArgs("IsChecked")); 
         } 
         Console.WriteLine(Name + " = " + _isChecked); 
        } 
       } 
      } 
      bool _isChecked; 

      public event PropertyChangedEventHandler PropertyChanged; 
     } 
    } 
} 

MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <ListBox ItemsSource="{Binding Thingies}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <UniformGrid Rows="1" Width="400"> 
        <TextBlock Text="{Binding Name}" /> 
        <CheckBox IsChecked="{Binding IsChecked}" /> 
       </UniformGrid> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Window> 
+0

Вы правы. Это тоже работает в моем проекте, и, глядя на это, я обнаружил, что один из моих экземпляров тоже работает. Я изучаю, почему это не работает в некоторых случаях, но у меня есть ощущение, что есть какой-то стиль, который мешает, потому что я вижу различные «избранные» визуальные эффекты в случаях, которые не работают. Большое спасибо за это. Я искал решение в другом месте. –

Смежные вопросы