将自定义控件双击事件绑定到MainViewModel命令

时间:2014-01-22 04:51:53

标签: c# wpf custom-controls

我有一个包装面板,由我的自定义控件的多个实例填充," GameIconControl。"我的目标是在双击自定义控件时将它们从包装面板中删除。

包装面板绑定到ObservableCollection。

以下是自定义控件xaml。我尝试添加双击命令绑定,但是一旦它在加权面板中加载,它就不知道如何找到命令。作为一个实验,当MainViewModel加载每个GameIconControl时,我尝试将每个的DataContext设置为" this,"因为MainViewModel是命令所在的位置。没有运气。

<Style TargetType="{x:Type assets:GameIconControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type assets:GameIconControl}">
                <Border Margin="3"
                        Background="Transparent"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <StackPanel HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Orientation="Vertical">

                        <Image Source="{TemplateBinding Icon}" />
                        <ContentPresenter Height="Auto"
                                          Margin="3"
                                          HorizontalAlignment="Center"
                                          ContentSource="GameName" />
                    </StackPanel>
                        <i:Interaction.Triggers>
                            <i:EventTrigger EventName="MouseDoubleClick">
                                <command:EventToCommand Command="{Binding MoveGameIconToGamesList, Mode=OneWay}" />
                            </i:EventTrigger>
                        </i:Interaction.Triggers>
                </Border>

            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

控件背后的代码很简单。三个DP和构造函数:

static GameIconControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(GameIconControl), new FrameworkPropertyMetadata(typeof(GameIconControl)));
    }

    public GameIconControl(){}

    public GameIconControl(string name, BitmapImage icon)
    {
        Icon = icon;
        GameName = name;
    }

    public GameIconControl(string name, BitmapImage icon, Game game) {
        GameForControl = game;
        Icon = icon;
        GameName = name;
    }

    public const string IconPropertyName = "Icon";
    public const string GameNamePropertyName = "GameName";
    public const string GamePropertyName = "Game";


    public string GameName
    {
        get { return (string)GetValue(GameNameProperty); }
        set { SetValue(GameNameProperty, value); }
    }

    public static readonly DependencyProperty GameNameProperty =
        DependencyProperty.Register(GameNamePropertyName, typeof(string), typeof(GameIconControl), new UIPropertyMetadata(default(string)));


    public BitmapImage Icon
    {
        get { return (BitmapImage)GetValue(IconProperty); }
        set { SetValue(IconProperty, value); }
    }

    public static readonly DependencyProperty IconProperty =
        DependencyProperty.Register(IconPropertyName, typeof(BitmapImage), typeof(GameIconControl), new PropertyMetadata(default(BitmapImage)));


    public Game GameForControl
    {
        get { return (Game)GetValue(GameProperty); }
        set { SetValue(GameProperty, value); }
    }

    public static readonly DependencyProperty GameProperty =
        DependencyProperty.Register(GamePropertyName, typeof(Game), typeof(GameIconControl), new PropertyMetadata(default(Game)));
}

非常感谢任何帮助。

最后,这是开场的xaml。我使用的是MVVM Lite:

<Window x:Class="Saved_Game_Backup.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cc="clr-namespace:Saved_Game_Backup.Assets"
    xmlns:command="http://www.galasoft.ch/mvvmlight"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
    xmlns:viewModel="clr-namespace:Saved_Game_Backup.ViewModel"
    DataContext="{Binding Path=Main,
                          Source={StaticResource Locator}}">

2 个答案:

答案 0 :(得分:1)

我认为MainViewModel不是GameItemControl的DataContext。要解决此问题,您可以为MainViewModel创建一个StaticResource并在绑定中使用它。以下代码段将为您提供帮助,

    <WrapPanel.Resources>
      <local:MainViewModel x:Key="viewModel" />
    </WrapPanel.Resources>

    <command:EventToCommand Command="{Binding MoveGameIconToGameList,Mode=OneWay,     

            Source={StaticResource viewModel}}" />

如果有帮助,请告诉我。

此致 Riyaj Ahamed I

答案 1 :(得分:1)

抱歉,你做错了所有错误。在WPF中,我们操纵数据项,而不是 UI元素。因此,要创建场景,您需要创建一个数据类型类(实现INotifyPropertyChanged interface)然后声明一个DataTemplate,它定义了您的类的每个实例应该在UI中的样子...在您的情况下,您的DataTemplate会有GameIconControl。将这些类的集合绑定到集合控件的ItemsSource属性,Framework将为您完成所有渲染工作。

这样,您可以直接从视图模型中的DataTemplate绑定到Command,并且在尝试将数据绑定到UserControl的属性时没有任何问题。更好的是,要从UI中删除项目,您只需要在视图模型中从集合中删除项目,UI将自动更新。

为了您将来的参考,通常设置DataContext的{​​{1}}是个好主意。您可以使用UserControl来访问UserControl DependencyProperty,而不是这样做:

RelativeSource Binding

此外,您可以绑定到<TextBlock Text="{Binding PropertyName, RelativeSource={RelativeSource AncestorType={ x:Type views:Saved_Game_Backup.MainWindow}}}" /> 上设置的任何 Command的属性或DataContext(最好来自外部控件)像这样:

UserControl