【问题标题】:UWP ListView Button MVVM BindingUWP ListView 按钮 MVVM 绑定
【发布时间】:2017-10-30 16:24:06
【问题描述】:

我有一个ListView,现在在SelectedItem 上打开一个弹出窗口。 我想要的是,如果用户决定从列表中删除一个项目,他可以单击按钮并将其删除 - 现在按钮确实会触发,但是我如何告诉 VM 中的按钮要删除哪些项目 - 没有“选定项目”? p.e..

<ListView 
 SelectedItem="{Binding...}"
 x:Name="lv">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Image Source="{Binding...}"/>
                <Button Command="{Binding ElementName=lv,Path=DataContext.RemoveXCommand}" />
            </Stackpanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

虚拟机

public void RemoveXCommand()
    {
    foreach(var item in pseudo)
       {
       if(item.Name == ?????)
           pseudo.Remove(item);
       }
    }

有没有办法,还是我必须把Popup的开口去掉,作为另一个Button来实现,这样我就可以用SelectedItem来比较了?

谢谢。

编辑1:

感谢Fruchtzwerg 我搞定了

public RelayCommand<string> RemoveXCommand{ get; private set; }

//... in then Constructor
RemoveXCommand = new RelayCommand<string>((s) => RemoveXCommandAction(s));

public void RemoveXCommand(object temp)
{
foreach(var item in pseudo)
   {
   if(item.Name == (string) temp)
       pseudo.Remove(item);
   }
}

【问题讨论】:

    标签: c# listview mvvm uwp


    【解决方案1】:

    您可以将需要删除的项目传递为CommandParameter

    <Button Command="{Binding ElementName=lv, Path=DataContext.RemoveXCommand}"
            CommandParameter="{Binding}"/>
    

    然后像这样删除它

    public void RemoveXCommand(object itemToRemove)
    {
        pseudo.Remove(itemToRemove);
    }
    

    您的方法也可以按名称删除项目。将item的Name绑定为CommandParameter

    <Button Command="{Binding ElementName=lv, Path=DataContext.RemoveXCommand}"
            CommandParameter="{Binding Name}"/>
    

    然后像这样删除它

    public void RemoveXCommand(object nameToRemove)
    {
        foreach(var item in pseudo)
        {
            if(item.Name == (string)nameToRemove)
            {
                pseudo.Remove(item);
            }
        }
    }
    

    请注意,第二种方法是删除具有您选择的项目名称的所有项目。第一种方法仅删除您选择的项目,因为特定实例已被删除。

    要允许RelayCommand 中的参数,需要ICommand 的新实现或修改实现。这是一个可能的解决方案:

    public class ParameterRelayCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Func<bool> _canExecute;
    
        public event EventHandler CanExecuteChanged;
    
        public ParameterRelayCommand(Action<object> execute)
            : this(execute, null)
        { }
    
        public ParameterRelayCommand(Action execute<object>, 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(parameter);
        }
    
        public void RaiseCanExecuteChanged()
        {
            var handler = CanExecuteChanged;
            if (handler != null)
            {
                handler(this, EventArgs.Empty);
            }
        }
    }
    

    【讨论】:

    • 如果我尝试这个,我的构造函数中出现错误(我在其中初始化。我的命令)“无法从方法转换为动作(已翻译。))RemoveXCommand = new RelayCommand(RemoveXCommandAction)
    • 这是因为RelayCommand 没有实现参数。看看stackoverflow.com/questions/33003207/…,你需要修改RelayCommand,在构造函数的action中加入object参数
    • 那我是不是必须用ICommand切换RelayCommand,如何在构造函数中添加参数呢?泰。
    • 我添加了ParameterRelayCommand的代码。你可以参加这个课程来创建命令。如果需要传递参数,只需使用ParameterRelayCommand 而不是RelayCommand
    • _execute是只读的,后来你设置_execute = execute?这让我很困惑,但多亏了你,我才得以正常工作。
    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 2021-06-27
    • 2019-04-13
    • 2017-05-14
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多