MVVM Listbox DataTemplate SelectedItem
本文关键字:SelectedItem DataTemplate Listbox MVVM | 更新日期: 2023-09-27 18:15:35
我使用一个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用于相应的按钮命令。当我点击TextBlock
或Border
时,SelectedItemVar确实更新,但当我点击任何一个按钮时都不会更新。我在这里找到了一个非mvvm解决方案。我不想在文件后面添加代码来解决这个问题,就像他们在链接中所做的那样。
是否有一个干净的解决方案可以在XAML中完成。除了非mvvm解决方案,我还没有发现任何人有这个问题。我本以为这是相当普遍的。
最后,我找到了这个用于命令绑定的Command="{Binding DataContext.CommandName} RelativeSource={RelativeSource FindAncestor, ListBox, 1}
。我不完全理解它在做什么,但我知道当我直接绑定到CommandName
时,命令没有触发。
您正在使用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项....
应该这样做......:)
标题>您需要一些代码来处理您想要的视觉行为,但您不必将其放在视图模型或控件代码中。
我会写一个行为(称为像SelectListBoxItemWhenClickedBehavior),当按钮被点击时,它查找ListBoxItem在可视化树(使用VisualTreeHelper)。然后它可以设置ListBoxItem。IsSelected = true.
该行为只做一件已知的事情,它只由控件的视觉样式(XAML)设置,该样式知道按钮位于ListBoxItem中。我认为这可以保持M-V-VM的关注点分离。
如果你需要帮助写一个行为,告诉我。