ICommand不会使用ItemTemplate中的按钮触发

时间:2013-02-02 23:34:37

标签: mvvm-light

我目前正在使用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被点击了?

1 个答案:

答案 0 :(得分:0)

您使用的是mvvm-light的relaycommand吗? 我使用命令参数将信息传递给命令方法:

<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"  />

然后在您的视图模型中:

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;
}

您可以将“YourUniqueIdentifyingVariable”绑定到记录的ID或您可以在命令方法中处理的其他值

代码未经测试但应该有效