我正在处理一个视图(称为“Familify'”),该视图向用户显示资产列表,并允许他们从列表中删除资产。资产存储在ViewModel中的ObservableCollection
中,因此删除命令只需获取资产对象并将其从集合中删除。我在删除'删除'功能工作。这是XAML和代码隐藏:
Familify.xaml
<ListView
ItemsSource="{Binding Assets}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80px" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="150px" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="60px" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text="{Binding number}" FontFamily="Consolas"/>
<TextBlock
Grid.Column="1"
Text="{Binding type}"/>
<TextBlock
Grid.Column="2"
Text="add binding here"/>
<TextBlock
Grid.Column="3"
Text="add binding here"/>
<Button
Command="{x:Bind ViewModel.RemoveAssetCommand}"
CommandParameter="{Binding}"
Content=""
FontFamily="Segoe MDL2 Assets"
Grid.Column="4">
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Familify.xaml.cs
namespace asset_manager.Views
{
public sealed partial class Familify : UserControl
{
FamilifyViewModel ViewModel { get; set; }
public Familify()
{
this.InitializeComponent();
DataContextChanged += (s, e) =>
{
ViewModel = DataContext as FamilifyViewModel;
};
}
}
}
想法是单击该按钮可从列表中删除资产。 (请注意,显示number
,type
等的正常绑定工作正常。)到目前为止我的想法:
binding
访问页面视图模型中存储的RemoveAssetCommand
。但是,我无法获得祖先绑定工作(即尝试在XAML层次结构中找到更高元素的数据上下文并不起作用,因为findAncestor
在UWP中不是什么事情。)x:Bind
看起来是一个很好的解决方案,因为它使用了属性的显式路径。所以,如果我在我的代码中声明ViewModel
,我可以使用x:Bind ViewModel.property
。一切都很好。我这样做了,intellisense允许我在输入时访问ViewModel.RemoveAssetCommand。no DataType defined for DataTemplate
。这是有道理的,所以我尝试了两件事。x:DataType="Models:Asset"
(放在上面的DataTemplate
标签中)是数据模板中显示的模型,所以我先尝试了。当然,该命令未在模型中声明,它在视图模型中声明,因此无法正常工作。x:DataType="ViewModels:FamilifyViewModel"
,认为我可以使用x:Bind
。但是,我得到一个错误,它无法将Asset
类型的对象强制转换为FamilifyViewModel
。这是有道理的,因为传递给此数据模板的对象属于Asset
。这很痛苦,因为我认为x:Bind
可以工作的全部原因是我可以直接从代码隐藏中的ViewModel访问该属性。
明确说明,1)是否可以在数据模板中使用x:Bind
来访问ViewModel
上的基本级别属性(在本例中为Prism命令)? 2)有没有更好的方法来实现这个功能?
答案 0 :(得分:1)
是否可以在数据模板中使用x:Bind来访问ViewModel上的基本级别属性(在本例中为Prism命令)?
是的,如果要访问基本级别,可以重新分配按钮的DataContext,如下所示:
<Button DataContext="{Binding ElementName=Familily, Path=DataContext}"/>
Family
是UserControl
的名称。
有没有更好的方法来实现此功能?
当您将commad
放入ViewModel
并按上述方式绑定按钮时。按钮的绑定项将成为系列DataContext
。因此,您无法直接在ViewModel
。
实现此功能的最佳做法是将RemoveAssetCommand
放入Asset
类。并使用ItemsSource
ListView
作为Button
CommandParameter
。
<Button
Command="{Binding RemoveAssetCommand}"
CommandParameter="{Binding ElementName=MyListView, Path=ItemsSource}"
Content=""
FontFamily="Segoe MDL2 Assets"
Grid.Column="4">
</Button>
<强> Asset.cs 强>
public class Asset
{
public string number { get; set; }
public string type { get; set; }
public ICommand RemoveAssetCommand
{
get
{
return new CommandHandler<ObservableCollection<Asset>>((item) => this.RemoveAction(item));
}
}
private void RemoveAction(ObservableCollection<Asset> items)
{
items.Remove(this);
}
}
<强> ViewModel.cs 强>
public class FamilifyViewModel
{
public ObservableCollection<Asset> Assets = new ObservableCollection<Asset>();
public FamilifyViewModel()
{
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
}
}