1

我目前正在使用 ICommand 进行测试,我想知道为什么 ICommand 不使用 ListBox.ItemTemplate 中的按钮触发。但是在模板之外使用时,它可以工作。

这是窗口 xaml

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1" x:Class="WpfApplication1.Window2"
        Title="Window2" Height="300" Width="300">
    <Window.DataContext>
        <local:W2VM/>
    </Window.DataContext>

    <Grid>
        <ListBox x:Name="listHistory" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemsSource="{Binding History}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <TextBlock Text="{Binding ''}" />
                        <Button 
                            Grid.Column="1" 
                            HorizontalAlignment="Right" 
                            x:Uid="btnDeleteHistoryItem" 
                            x:Name="btnDeleteHistoryItem" 
                            Content="r" 
                            FontFamily="Marlett" 
                            Visibility="Hidden" Command="{Binding MeClick}" 

                            />
                    </Grid>

                    <DataTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="Visibility" TargetName="btnDeleteHistoryItem" Value="Visible" />
                        </Trigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        <Button Content=" exit " VerticalAlignment="Bottom" Command="{Binding ExitCommand}" />
    </Grid>
</Window>

这是完整的 ViewModel 代码

using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for Window2.xaml
    /// </summary>
    public partial class Window2 : Window
    {
        public Window2()
        {
            InitializeComponent();
        }
    }

    public class W2VM : ViewModelBase
    {
        public List<string> _History = new List<string>();
        public List<string> History
        {
            get { return this._History; }
        }

        public ICommand MeClick
        {
            get;
            internal set;
        }

        public ICommand ExitCommand
        {
            get;
            internal set;
        }

        public W2VM()
        {
            this.History.AddRange(new string[] {
                "jayson", "hello", "world"
            });

            this.MeClick = new RelayCommand(Test);
            this.ExitCommand = new RelayCommand(Exit);
        }

        void Exit()
        {
            Application.Current.Shutdown();
        }

        void Test()
        {
            Debug.WriteLine("hello world");

            MessageBox.Show("do something incredible");
        }
    }
}

Test() 不触发


好的,我得到了它的工作..

<Window.Resources>
    <me:W2VM x:Key="local" />
</Window.Resources>

代替

<Window.DataContext>
    <local:W2VM/>
</Window.DataContext>

和我的窗格

<Grid DataContext="{StaticResource local}">
    <ListBox x:Name="listHistory" BorderThickness="0" Margin="0" Padding="0" HorizontalContentAlignment="Stretch" ItemsSource="{Binding History}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding ''}" />
                    <Button 
                        Grid.Column="1" 
                        HorizontalAlignment="Right" 
                        x:Uid="btnDeleteHistoryItem" 
                        x:Name="btnDeleteHistoryItem" 
                        Content="r" 
                        FontFamily="Marlett" 
                        Visibility="Hidden" Command="{Binding MeClick, Source={StaticResource local}}"  />
                </Grid>

                <DataTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Visibility" TargetName="btnDeleteHistoryItem" Value="Visible" />
                    </Trigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <Button Content=" exit " VerticalAlignment="Bottom" Command="{Binding ExitCommand}" />
</Grid>

现在这将提出另一个问题。

刚刚路由 btnDeleteHistoryItem 命令时,我如何知道单击了哪个 ListViewItem?

4

1 回答 1

0

Are you using the relaycommand of mvvm-light? I use command parameters to pass information to the command method:

<Button 
                        Grid.Column="1" 
                        HorizontalAlignment="Right" 
                        x:Uid="btnDeleteHistoryItem" 
                        x:Name="btnDeleteHistoryItem" 
                        Content="r" 
                        FontFamily="Marlett" 
                        Visibility="Hidden" Command="{Binding MeClick, Source=StaticResource local}}" 
                        CommandParameter="YourUniqueIdentifyingVariable"  />

and then in your view model:

public RelayCommand<string> MeClick{
    get { return _MyClick; }
    private set { _MyClick = value; }
}

public New()
{

    MeClick = new RelayCommand<string>(MySub, MySubIsEnabled);
}

private void MySub(string sParam)
{
    //do stuff here, YourUniqueIdentifyingVariable is sParam
}

private bool MySubIsEnabled(string sParam)
{
    return true;
}

you can bind "YourUniqueIdentifyingVariable" to the ID of the record or some other value that you can process in your command method

Code is untested but should work

于 2013-02-06T16:20:33.690 回答