2014-01-22 114 views
0

我有一个由我的自定义控件“GameIconControl”的多个实例填充的包装面板。我的目标是在双击自定义控件时让它们从包装面板中删除。将自定义控件双击事件绑定到MainViewModel命令

包装面板绑定到一个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精简版:

<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}}"> 
+1

尝试使用'的RelativeSource FindAncestor'结合如图[这里](http://stackoverflow.com/a/1127964/2998271)。这使您可以绑定到控件的父级DataContext,但没有在你的情况下从样式中尝试它。 – har07

回答

1

很抱歉,但你这样做所有错误。在WPF中,我们操纵数据项目,而不是UI元素。因此,要创建您的场景,您需要创建一个数据类型类(实现INotifyPropertyChanged interface),然后声明DataTemplate,该类定义您的类的每个实例应该在用户界面中看起来像什么...在您的情况下,您的DataTemplate会有一个GameIconControl在里面。将这些类的集合绑定到集合控件的ItemsSource属性,并且框架将为您完成所有渲染工作。

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

为了您的未来参考,通常是而不是是一个好主意,您可以像那样设置DataContext。而不是这样做,则可以使用一个RelativeSource Binding这样访问UserControl DependencyProperty S:

<TextBlock Text="{Binding PropertyName, RelativeSource={RelativeSource AncestorType={ 
    x:Type views:Saved_Game_Backup.MainWindow}}}" /> 

此外,可以绑定到一个属性或Command即从任何DataContext即在UserControl设置(优选从控制)所示:

<TextBlock Text="{Binding DataContext.PropertyName, RelativeSource={RelativeSource 
    AncestorType={x:Type views:Saved_Game_Backup.MainWindow}}}" /> 
+0

谢谢。试图在控件上设置DataContext只是我没有经验的挫败试图让它工作。即使对我来说这似乎也是错误的,但我不知道如何继续。渲染已经在一个包装面板中完成,并且正在使用添加/删除它们的方式正常工作,但是除了在面板中双击它们之外的其他方法。 – CubemonkeyNYC

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艾哈迈德我

+0

正在混淆我的xaml。我没有一个本地命名空间。 ViewModels位于名称空间“viewModel”中,因此它将它强制为但仍然中断。我添加了窗口的开始xaml。 – CubemonkeyNYC

相关问题