使用棱镜库将ListView项目传递给命令 [英] Passing ListView Items to Commands using Prism Library

查看:96
本文介绍了使用棱镜库将ListView项目传递给命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于listview项目数据执行方法.除此之外,仅当列表视图项的"CanExecute"方法返回true时,才应启用触发命令的按钮.

I'm trying to execute methods based on listview items data. In addition to that, the button, which triggers the command, should only be enabled, if "CanExecute" method of the listview item returns true.

ViewModel中包括"MyCommand"和"CanExecute"这两种方法. 不幸的是,我不确定如何正确地将商品信息传递给这两种方法,以符合PRISM 6框架.

Both methods, "MyCommand" and "CanExecute", are included in my ViewModel. Unfortunately I'm not sure how to pass the items information correctly to both methods in order to be conform with the PRISM 6 framework.

所以我的第一种方法是像下面这样:

So my first approach was to do it like the following :

模型

public class MyModel
{
    public string Name { get; set; }
    public string Version { get; set; }
    public int Identifier { get; set; }
}

ViewModel

public class MyViewModel : BindableBase
{

    private ObservableCollection<MyModel> _models = new ObservableCollection<MyModel>();
    public ObservableCollection<MyModel> Models
    {
        get { return _models; }
        set { SetProperty(ref _models, value); }
    }

    public DelegateCommand VerifyCommand { get; set; }


    public MyViewModel()
    {
        //Add test data
        for (int i = 0; i < 5; i++)
        {
            MyModel model = new MyModel();
            model.Name = "Random Text";
            model.Version = "Random Text";
            model.Identifier = i;

            Models.Add(model);
        }

        //Doesn't work, because I don't reference to "Models"
        //How to do that?
        VerifyCommand = new DelegateCommand(DoCommand, CanExecute).ObservesProperty<string>(() => Name).ObservesProperty<string>(() => Version);
    }

    private bool CanExecute()
    {
        //Obviously this doesn't work, because "Version" and "Name" 
        //don't belong to the selected "Models" item of the listview

        //What is the "bridge", to know which item of Models was clicked (button)
        return !String.IsNullOrWhiteSpace(Version) && !String.IsNullOrWhiteSpace(Name);
    }

    private void DoCommand()
    {
        //Do something special
    }
}

查看

<ListView ItemsSource="{Binding Models}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Height="Auto" Margin="0,0,0,10">
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <TextBox Grid.Row="0" Tag="VERSION" Text="{Binding Version, UpdateSourceTrigger=PropertyChanged}" />
                <TextBox Grid.Row="1" Tag="NAME" Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
                <Button Command="{Binding ElementName=root, Path=DataContext.VerifyCommand}" Content="Verify" Grid.Row="2">
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

使用以下方法完成View和ViewModel之间的链接:

The link between View and ViewModel is done by using:

prism:ViewModelLocator.AutoWireViewModel="True"

在我看来(可行).

因此,总而言之: PRISM的工作原理是:1.仅在CanExecute为true时才启用项目按钮;以及2.执行"DoCommand"方法并将项目信息传递给该方法(按钮的根元素->在这种情况下为ListViewItem(MyModel ).

So in summary: How does it work, PRISM conform, to 1. Enable the items button only if CanExecute is true and 2. to execute "DoCommand" method and passing items information to that (root element of the button -> In this case the ListViewItem (MyModel).

任何帮助将不胜感激.

推荐答案

简短的答案:将命令放在项目的视图模型中.

Short answer: put the command in the item's viewmodel.

长答案:

这是我在上面的评论中所表达的意思的一个示例.我已经省略了集合的可观察性,如果您确实需要模型的可观察集合和视图模型的可观察集合,请准备许多无聊的双向同步代码...

Here's an example of what I mean in the comment above. I've omitted the observability of the collections, if you really need an observable collection of models and an observable collection of view models, prepare yourself for a lot of boring two-way-sync-code...

型号:

internal class ItemModel
{
    public string Name { get; set; }
    public string Version { get; set; }
    public int Identifier { get; set; }
}

ViewModels(一个用于收集项目,即您的MyViewModel,另一个用于收集项目):

ViewModels (one for the collection of items, that is, your MyViewModel, and one for the item):

internal class MyCollectionViewModel : BindableBase
{
    private readonly List<ItemModel> _models = new List<ItemModel>();

    public MyCollectionViewModel()
    {
        //Add test data
        for (var i = 0; i < 5; i++)
            _models.Add( new ItemModel
            {
                // to prove that CanExecute is actually evaluated...
                Name = i == 3 ? "Random Text" : string.Empty,
                Version = "Random Text",
                Identifier = i
            } );
    }

    public IReadOnlyCollection<ItemViewModel> TheCollection => _models.Select( x => new ItemViewModel( x ) ).ToList();
}

internal class ItemViewModel : BindableBase
{
    public ItemViewModel( ItemModel item )
    {
        _item = item;
        VerifyCommand = new DelegateCommand( () =>
                                             {
                                                 /* Do something */
                                             }, () => !string.IsNullOrWhiteSpace( Version ) && !string.IsNullOrWhiteSpace( Name ) );
    }

    public string Name => _item.Name;
    public string Version => _item.Version;
    public int Identifier => _item.Identifier;

    public DelegateCommand VerifyCommand
    {
        get;
    }

    private readonly ItemModel _item;
}

查看:

<ListView ItemsSource="{Binding TheCollection}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <Grid Height="Auto" Margin="0,0,0,10">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <TextBox Grid.Column="0" Text="{Binding Version, Mode=OneWay}" />
                <TextBox Grid.Column="1" Text="{Binding Name, Mode=OneWay}" />
                <Button Grid.Column="2" Command="{Binding VerifyCommand}" Content="Verify"/>
            </Grid>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

这篇关于使用棱镜库将ListView项目传递给命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆