Шаблон списка данных MVVM SelectedItem - PullRequest
2 голосов
/ 25 ноября 2011

Я использую ListBox с DataTemplate, как показано ниже (упрощенный xaml и имена переменных изменены).

<ListBox ItemsSource="{Binding Path=ObservCollectionItems}"
         SelectedItem="{Binding Path=SelectedItemVar, Mode=TwoWay}">
         <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding SomeVar}" />
                    <Border>
                        <StackPanel>
                            <Button Content="String1"
                                    Command="{Binding DataContext.Command1}
                                    RelativeSource={RelativeSource FindAncestor, ListBox, 1}}" />
                            <Button Content="String2" 
                                    Command="{Binding DataContext.Command2}
                                    RelativeSource={RelativeSource FindAncestor, ListBox, 1}}" />
                        </StackPanel>
                    </Border>
                </StackPanel>
            </DataTemplate>
         <ListBox.ItemTemplate>
 </ListBox>

Мне нужно обновить SelectedItemVar (свойство зависимостей), когда я нажимаю на один изкнопки.SelectedItemVar затем используется для команды соответствующей кнопки.SelectedItemVar обновляется, когда я нажимаю TextBlock или Border, но не когда я нажимаю любую кнопку.Я нашел не-MVVM решение этой проблемы здесь .Я не хочу добавлять код в файл для решения этой проблемы, как они сделали по ссылке.

Есть ли чистое решение, которое можно сделать в XAML.Помимо не-MVVM решений, я не нашел никого с этой проблемой.Я бы подумал, что это довольно распространено.

Наконец-то я нашел это Command="{Binding DataContext.CommandName} RelativeSource={RelativeSource FindAncestor, ListBox, 1} для привязки команд.Я не до конца понимаю, что он делает, но я знаю, что команда не запускалась, когда я непосредственно связывался с CommandName.

Ответы [ 2 ]

3 голосов
/ 25 ноября 2011

Вы используете MVVM .... таким очень простым решением является передача SelectedItem в качестве параметра команде кнопки Both, а затем установка SelectedItem со значением параметра .....

код

public class YourViewmodel
{
     //Other Variables


     public YourViewModelCtor()
     {
        Command1= new RelayCommand(Command1Func);
     }

     Public SelectedVar
     {
             get {return value;}
             Set { selectedVar=value;
                       OnPropertyChanged("SelectedVar");
              }
     }

     //Other Properties


     void Command1Func(object obj)
     {
              SelectedVar= obj as <Your Desired Type>;

              //Do your thing with SelectedVar ... Do the same for Command2
     }
}

Изменения, необходимые в Xaml

<StackPanel>
    <Button Command="{Binding DataContext.Command1}" CommandParameter="{Binding}"
            Content="String1" />
    <Button Command="{Binding DataContext.Command2}" CommandParameter="{Binding}"
            Content="String2" />
</StackPanel>

Это даст вам текущий элемент списка ListBox, в котором вы нажали кнопку ....

Это должно сделать это ......:)

2 голосов
/ 25 ноября 2011

Вам нужен код для обработки нужного вам визуального поведения, но вам не нужно помещать его в модель представления или в свой контрольный код.

Я бы написал поведение (называемое чем-то вроде SelectListBoxItemWhenClickedBehavior), что при нажатии кнопки он ищет ListBoxItem в визуальном дереве (используя VisualTreeHelper). Затем он может установить ListBoxItem.IsSelected = true.

Поведение делает одну известную вещь, и оно устанавливается только визуальным стилем элемента управления (XAML), который знает, что кнопка находится внутри ListBoxItem. Я думаю, что это сохраняет разделение проблем для M-V-VM.

Если вам нужна помощь в написании поведения, дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...