gpt4 book ai didi

c# - 当 ItemTemplate 是用户控件时,如何从 ListView 中正确删除项目?

转载 作者:行者123 更新时间:2023-12-03 10:22:38 25 4
gpt4 key购买 nike

我试着按照这里的例子:

WPF ListBox with self-removing items

这是有道理的,但我的问题是,ListView 本身正在确定使用的模板。因此它可以轻松自定义绑定(bind)以指向正确的目标。然而,我正在使用 MVVM 并且正在努力将两者结合在一起。

例如,如果模板是:

<ListBox.ItemTemplate>
<DataTemplate>
<local:MyItemView/>
</DataTemplate>
</ListBox.ItemTemplate>

这突然变得更加困难,理想情况下,我想重用该 View 而不对绑定(bind)进行硬编码。

我尝试使用 DependencyProperty通过 ListElement通过,所以我可以通过命令删除它。
<ListBox.ItemTemplate Name="myList">
<DataTemplate>
<local:MyItemView TheList={Binding ElementName=myList, Path=DataContext.List} TheElement={Binding}/>
</DataTemplate>
</ListBox.ItemTemplate>

但是,我遇到绑定(bind)错误,告诉我它无法转换 TheElement 的值来自 MyClassViewModelMyClass .即使我评论了 TheList始终为 NULL。

基本上我想要:
class MyDataClass { // pretend there's more here}

class MyDataClassContainer
{
public ObservableCollection<MyDataClass> Items;
public void Add(MyDataClass);
public void Remove(MyDataClass);
}

class MyDataClassEntryViewModel
{
public static readonly DependencyProperty ListItemProperty = DependencyProperty.Register("TheClass", typeof(MyDataClass), typeof(MyDataClassEntryViewModel));
public static readonly DependencyProperty ListContainerProperty = DependencyProperty.Register("TheContainer", typeof(MyDataClassContainer), typeof(MyDataClassEntryViewModel));

public MyDataClass TheClass;
public MyDataClassContainer TheContainer;
public ICommand Delete = new DelegateCommand(RemoveItem);

private function RemoveItem(object parameter)
{
TheContainer.Remove(TheClass);
}
}

使用以下模板:

MyDataClassEntryView.xaml
<UserControl>
<Grid>
<Button Content="Delete" Command="{Binding Path=Delete}"/>
</Grid>
</UserControl>

MyDataContainerView.xaml
<UserControl>
<ListView x:Name="listView" ItemsSource="{Binding Path=Container.Items}">
<ListView.ItemTemplate>
<DataTemplate>
<local:MyDataClassEntryView TheClass="{Binding}" TheContainer="{Binding ElementName=listView, Path=DataContext.Container}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>

注意:我省略了大部分多余的行,因为我试图获得一个可以在任何地方使用的通用答案。不是硬编码的单一解决方案。我基本上是想保持 MVVM 结构的强大,在后台没有大量的硬编码和布线。我想尽可能多地使用 XAML。

我看到的与从列表中删除有关的所有其他方法都需要各种假设,例如使用 SelectedIndex/Item,或者使用 ContainerView 本身的方法将元素作为参数,转换它,然后删除,等等。简而言之,大多数解决方案对于给定的示例都过于硬编码。感觉应该有一种简单的方法可以在 WPF 中实现这一点。

由于 ListView 会自动创建我的子 ViewModel/Views 的实例,因此我显然无法获取任何数据。基本上,我只想使用绑定(bind)传递参数。

最佳答案

您的按钮应如下所示:

<Button Content="Delete" 
Command="{Binding Path=Delete}"
CommandParameter="{Binding}/>

然后删除命令应如下所示:
private function RemoveItem(object parameter)
{
var item = parameter as MyDataClass
if(item != null)
TheContainer.Remove(item);
}

您不需要将列表传递给 ItemTemplate 中的 UserControl,因为它根本不需要知道列表

编辑:
我读了你的问题几次,看看你对什么感到困惑,所以我会试着澄清一下。

无论 ListView 在 Xaml 中设置自己的模板,还是您使用另一个 UserControl,datacontext 仍会传递给项目。无论您决定如何对项目进行模板化,ItemTemplate 都将拥有 ListView 项目列表中单个项目的数据上下文。

我认为你的困惑来自于在模板之外引入控件。把你带进来的控件的Xaml想象成在运行程序的时候被剪切并粘贴到ListView的DataTemplate中,然后真的和在那里硬编码没什么区别。

关于c# - 当 ItemTemplate 是用户控件时,如何从 ListView 中正确删除项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35917930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com