【问题标题】:MVVM, Button in a ItemsControl, ICommandMVVM,ItemsControl 中的按钮,ICommand
【发布时间】:2018-02-17 18:07:40
【问题描述】:

尝试使用 ICommand/RelayCommand 在按钮上实现命令时遇到问题,当您按下列表中的按钮时,它会删除该项目。

我查找了 ICommand/Relay Command,并多次尝试实现它,但没有成功。我想我还需要传递一个参数(BaseItem 类型)以从 BaseList 中删除。

我也不确定从列表中删除项目的方法应该放在模型还是视图模型中。如果它在模型中,我需要以某种方式获取对 BaseList 的引用来调用 BaseList.Remove()?

到目前为止我的代码,

查看

<Window x:Class="WpfApp3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp3"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:TillViewModel/>
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <ItemsControl ItemsSource="{Binding BaseList}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel/>
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.Resources>
                    <DataTemplate DataType="{x:Type local:FirstType}">
                        <StackPanel Background="Black"  Orientation="Horizontal">
                            <TextBlock Foreground="White" Text="{Binding Name}"/>
                            <TextBlock Foreground="White" Text=" - "/>
                            <TextBlock Foreground="White" Text="{Binding ProductType}"/>
                            <Button CommandParameter="{Binding MyList}" Content="X" />
                        </StackPanel>
                    </DataTemplate>
                    <DataTemplate DataType="{x:Type local:SecondType}">
                        <StackPanel Background="BurlyWood" Orientation="Horizontal">
                            <TextBlock Text="{Binding Name}"/>
                            <TextBlock Text=" - "/>
                            <TextBlock Text="{Binding ModelType}"/>
                            <Button Content="X"/>
                        </StackPanel>
                    </DataTemplate>
                </ItemsControl.Resources>
            </ItemsControl>
        </StackPanel>
    </Grid>
</Window>

ViewModel(F1、F2、S1暂时进入构造函数,顺便看看实际效果)

public class TillViewModel
{
    private ObservableCollection<BaseItem> _BaseList = new ObservableCollection<BaseItem>();
    public ObservableCollection<BaseItem> BaseList
    {
        get
        {
            return _BaseList;
        }
        set
        {
            _BaseList = value;
        }
    }

    public TillViewModel()
    {
        FirstType F1 = new FirstType() { Name = "Colgate", ProductType = "ToothPaste" };
        FirstType F2 = new FirstType() { Name = "Walkers", ProductType = "Crisps" };
        SecondType S1 = new SecondType() { Name = "Ford", ModelType = "Focus" };

        BaseList.Add(F1);
        BaseList.Add(F2);
        BaseList.Add(S1);
    }
}

模型

public class BaseItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    protected bool SetField<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    private string _Name;
    public string Name
    {
        get => _Name;
        set { SetField(ref _Name, value, nameof(Name)); }
    }

    public BaseItem()
    {

    }
}


public class FirstType : BaseItem
{
    private string _ProductType;
    public string ProductType
    {
        get => _ProductType;
        set { SetField(ref _ProductType, value, nameof(ProductType)); }
    }

    public FirstType()
    {

    }

}

public class SecondType : BaseItem
{
    private string _ModelType;
    public string ModelType
    {
        get => _ModelType;
        set { SetField(ref _ModelType, value, nameof(ModelType)); }
    }

    public SecondType()
    {

    }
}

【问题讨论】:

    标签: c# wpf mvvm icommand relaycommand


    【解决方案1】:

    首先,将BaseList 对象传递给所有BaseItem 对象(例如,使用BaseItem 构造函数将其注入)。然后,在按钮命令处理程序中,您可以使用BaseList.Remove(this); 从集合中删除BaseItem 对象。

    至于命令,你必须将ButtonCommand属性绑定到RelayCommand/ICommand对象。

    【讨论】:

    • 或者使用RelativeSource绑定找到包含父视图模型的父控件(或者只是在绑定中使用x:Name和ElementName),绑定到Remove ICommand,并有CommandParameter={Binding}通过要删除到命令的子对象。您的解决方案更简单。
    • 感谢您的提示。是的,我想这取决于攻角,如果你想要BaseItem 类或ViewModel 中的ButtonCommand 属性。
    猜你喜欢
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2010-11-30
    相关资源
    最近更新 更多