我是 UWP 的新手,我正在尝试从每个项目上显示的列表视图中的按钮浮出控件绑定到 ViewModel 中的事件。我在网上查看了许多解决方案并提出了以下代码,它编译良好,但是当我单击上述编辑按钮时没有任何反应。
我的视图模型可从页面的上下文而不是项目的上下文中使用
XAML
<ListView x:Name="MainListView"
ItemsSource="{x:Bind ViewModel.Devices, Mode=OneWay}"
SelectionMode="Multiple"
SelectionChanged="MainListView_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*"></ColumnDefinition>
<ColumnDefinition Width=".4*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="2" Text="{Binding AssetNumber}"/>
<TextBlock Grid.Column="3" Text="{Binding SerialNumber}"/>
<TextBlock Grid.Column="4" Text="{Binding Model}"/>
<Button Grid.Column="1" Height="30" Width="30">
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem Text="Edit" Icon="Edit"
Command="{Binding ElementName=MainListView,Path=DataContext.ViewModel.EditCommand}"
CommandParameter="{Binding}"/>
</MenuFlyout>
</Button.Flyout>
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
查看模型类
public class MainPageViewModel
{
// Elements contained in the main listview
public ObservableCollection<Device> Devices = new ObservableCollection<Device>();
public MainPageViewModel()
{
DeviceProvider.Fill(ref Devices, 100);
EditCommand = new RelayCommand<Device>(EditDevice);
}
public RelayCommand<Device> EditCommand { get; set; }
private async void EditDevice(Device device)
{
// Code here that creates a dialog
}
}
设备类
public class Device : INotifyPropertyChanged
{
private string assetNumber;
private string serialNumber;
private string model;
public string AssetNumber
{
get
{
return assetNumber;
}
set
{
assetNumber = value;
OnPropertyChanged();
}
}
public string SerialNumber
{
get
{
return serialNumber;
}
set
{
serialNumber = value;
OnPropertyChanged();
}
}
public string Model
{
get
{
return model;
}
set
{
model = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
中继命令类
public class RelayCommand<T> : ICommand
{
private readonly Action<T> _execute;
private readonly Func<bool> _canExecute;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<T> execute) : this(execute, null)
{
}
public RelayCommand(Action<T> execute, Func<bool> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
public void Execute(object parameter)
{
_execute((T)parameter);
}
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
}
您的代码似乎没有任何问题。所以它应该完美地工作。但如果不是,我怀疑MainPage.ViewModel成员可能没有正确定义。要在 {Binding} 中使用的属性必须是"公共"属性,并且必须具有"get"访问器。
public sealed partial class MainPage : Page
{
public MainPageViewModel ViewModel { get; set; } = new MainPageViewModel();
public MainPage()
{
this.InitializeComponent();
DataContext = this;
}
}
它编译得很好,但是当我单击上述编辑按钮时,没有任何反应。
问题是您为MenuFlyoutItem
绑定了错误的Path
(Path=DataContext.ViewModel.EditCommand(,请删除ViewModel
字段。我已经编辑了您的代码,请参阅以下内容。
<Page.DataContext>
<local:MainPageViewModel x:Name="ViewModel"/>
</Page.DataContext>
......
<Button
Grid.Column="1"
Width="30"
Height="30"
>
<Button.Flyout>
<MenuFlyout>
<MenuFlyoutItem
Command="{Binding ElementName=MainListView, Path=DataContext.EditCommand}"
CommandParameter="{Binding}"
Icon="Edit"
Text="Edit"
/>
</MenuFlyout>
</Button.Flyout>
</Button>