C# 使用Prism库将ListView项传递给命令

C# 使用Prism库将ListView项传递给命令,c#,mvvm,prism,routed-commands,C#,Mvvm,Prism,Routed Commands,我正在尝试执行基于listview项数据的方法。除此之外,只有当listview项的CanExecute方法返回true时,才应启用触发命令的按钮 MyCommand和CanExecute这两种方法都包含在我的ViewModel中。 不幸的是,我不知道如何将项目信息正确地传递给这两种方法,以符合PRISM 6框架 因此,我的第一个方法是按照以下方式进行: 模型 视图模型 在我看来,这是可行的 总而言之: 它是如何工作的,棱镜符合1。仅当CanExecute为true且为2时才启用items按钮。

我正在尝试执行基于listview项数据的方法。除此之外,只有当listview项的CanExecute方法返回true时,才应启用触发命令的按钮

MyCommand和CanExecute这两种方法都包含在我的ViewModel中。 不幸的是,我不知道如何将项目信息正确地传递给这两种方法,以符合PRISM 6框架

因此,我的第一个方法是按照以下方式进行:

模型

视图模型

在我看来,这是可行的

总而言之: 它是如何工作的,棱镜符合1。仅当CanExecute为true且为2时才启用items按钮。执行DoCommand方法并将项目信息传递给按钮的根元素->在本例中为ListViewItem MyModel


如果您有任何帮助,我们将不胜感激。

简短回答:将命令放在项目的viewmodel中

长答覆:

下面是我在上面评论中的意思的一个例子。我省略了集合的可观察性,如果您真的需要一个可观察的模型集合和一个可观察的视图模型集合,请为大量无聊的双向同步代码做好准备

型号:

internal class ItemModel
{
    public string Name { get; set; }
    public string Version { get; set; }
    public int Identifier { get; set; }
}
ViewModels一个用于项目集合,即MyViewModel,另一个用于项目:

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;
}
视图:


您的模型应该具有视图模型-这些模型随后携带命令。也就是说,视图有一个视图模型,该视图模型公开了一个ModelViewModels列表。顺便说一句-Models属性可能不需要setter,除非您计划通过数据绑定从外部进行设置…您是选择一个要验证的项还是可以从列表中选择多个项?
<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>
prism:ViewModelLocator.AutoWireViewModel="True"
internal class ItemModel
{
    public string Name { get; set; }
    public string Version { get; set; }
    public int Identifier { get; set; }
}
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>