我正在尝试在列表框组件上制作上下文折叠菜单,它有一个简单的但我无法设法使命令参数的绑定起作用。
这是我的用户控件 XAML 的简化视图。
<?xml version="1.0" encoding="utf-8"?>
<UserControl x:Name="userControl"
x:Class="SampleControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SampleUWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:inter="microsoft"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:ViewModel}">
<Grid>
<ListBox x:Name="myList" ItemsSource="{Binding ListSource}" DisplayMemberPath="Name">
<ListBox.ContextFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="Add" Command="{Binding Add}"/>
<MenuFlyoutItem Text="Remove" Command="{Binding Remove}" CommandParameter="{Binding SelectedItem, ElementName=myList}"/>
</MenuFlyout>
</ListBox.ContextFlyout>
</ListBox>
</Grid>
</UserControl>
ViewModel 的简单表示。
public class ViewModel
{
public ICommand Add {get;} // Ignored for now
public ICommand Remove {get;} = new DelegatedCommand(OnRemove, CanRemove)
public IEnumerable<Item> ItemSource {get;} = new [] {
new Item { Id = 1, Name = "First" },
new Item { Id = 2, Name = "Second" }
}
private bool CanRemove(object param)
{
// We want param to be the list item so we can get the Id
}
private OnRemove(object obj)
{
// Do some logic for removing
}
}
public class Item
{
public int Id {get;set;}
public string Name {get;set;}
}
我尝试在论坛上找到解决方案,但我尝试的任何方法都不起作用,我最接近的是使用
{Binding RelativeSource={RelativeSource Mode=Self}}
获取 MenuFlyoutItem 但我也不知道如何从这里获取列表框。
我知道上下文菜单本身位于不同的视觉树中,就像在 WPF 中一样,但我可以通过使用相对源并使用查找祖先来获取源,但在 UWP 中我无法找到有关如何绑定命令的解决方案列表项的参数,以便我可以将其作为参数发送。
需要提及的是,该命令没有问题,它可以毫无问题地解析为 ViewModel,但我无法弄清楚命令参数。
也许你可以尝试下面的代码。
Xaml:
<ListBox.ContextFlyout>
<MenuFlyout>
<!--<MenuFlyoutItem Text="Add" Command="{Binding Add}"/>-->
<MenuFlyoutItem Text="Remove" Command="{Binding Remove}" />
</MenuFlyout>
</ListBox.ContextFlyout>
ViewModel 代码隐藏:
public class ViewModel: INotifyPropertyChanged
{
public ICommand Add { get; } // Ignored for now
public ICommand Remove
{
get
{
return new CommadEventHandler<string>((s) => this.OnRemove(s));
}
}
public IEnumerable<Item> ItemSource { get; } = new[] {
new Item { Id = 1, Name = "First" },
new Item { Id = 2, Name = "Second" }
};
private int _selectedIndx;
public int SelectedIndx
{
get { return _selectedIndx; }
set
{
_selectedIndx = value;
RaisePropertyChanged("SelectedIndx");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
private void OnRemove(object obj)
{
// Do some logic for removing
if (SelectedIndx < 0 || SelectedIndx > ItemSource.Count())
{
return;
}
Item selectedItem = ItemSource.ElementAt(SelectedIndx);
Debug.WriteLine(selectedItem.Name);
}
}