2016-02-04 139 views
0

我想在我的自定义控件中添加一个方法,我可以使用命令绑定在我的MainWindow.xaml中调用一个按钮。我在网上遇到了一些解决方案,但其中一个解决方案看起来没有工作,另一个解决了。有人能向我解释设置这个的正确方法吗?第一种解决方案如下所述产生错误。第二种解决方案有效,但我不确定任何优点/缺点。向按钮绑定的自定义控件添加命令wpf

溶液1 - 碎

public partial class MyControl : Control 
{ 
    ... 
    public static readonly RoutedCommand AlignLeftCommand = null; 

    static MyControl() 
    { 
     binding = new CommandBinding(); 
     binding.Command = AlignLeftCommand; 
     binding.Executed += new ExecutedRoutedEventHandler(AlignLeft_Executed); 
     CommandManager.RegisterClassCommandBinding(typeof(MyControl), binding); 
    } 
} 

错误:

Severity Code Description Project File Line Error CS0120 An object reference is required for the non-static field, method, or property...

溶液2

public partial class MyControl : Control 
{ 
    ... 
    public static readonly RoutedCommand AlignLeftCommand = new RoutedCommand(); 

    public MyControl() 
    { 
     this.CommandBindings.Add(new CommandBinding(MyControl.AlignLeftCommand, AlignLeft_Executed, null)); 
    } 
} 

下面是按钮调用该方法。

<StackPanel Orientation="Horizontal"> 
    <Button Content="Left Edges" FontSize="8" 
      Command="{x:Static JM:MyControl.AlignLeftCommand}" 
      CommandTarget="{Binding ElementName=mycontrol}"/> 
</StackPanel> 
+1

是您的应用程序MVVM或代码隐藏? – StepUp

回答

1

起初,你应该在Window这样定义命令结合(创建处理程序ExecutedCanExecute事件):

<Window x:Class="CommandBindingWPF.MainWindow" 
     ...The code omitted for the brevity... 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.CommandBindings> 
     <CommandBinding Command="ApplicationCommands.New" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute" /> 
    </Window.CommandBindings> 

,并宣布你Button九XAML:

<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
    <Button Command="ApplicationCommands.New">New</Button> 
</StackPanel> 

处理程序应该在代码隐藏后创建mmand绑定创建:

private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e) 
{ 
    MessageBox.Show("Hello from Command"); 
} 

private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e) 
{  } 

更新:

对于MVVM应用:

public class RelayCommand : ICommand 
{ 
    #region Fields 

    readonly Action<object> _execute; 
    readonly Predicate<object> _canExecute; 

    #endregion // Fields 

    #region Constructors 

    public RelayCommand(Action<object> execute) 
     : this(execute, null) 
    { 
    } 

    public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
    { 
     if (execute == null) 
      throw new ArgumentNullException("execute"); 

     _execute = execute; 
     _canExecute = canExecute; 
    } 
    #endregion // Constructors 

    #region ICommand Members 

    public bool CanExecute(object parameter) 
    { 
     return _canExecute == null ? true : _canExecute(parameter); 
    } 

    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 

    public void Execute(object parameter) 
    { 
     _execute(parameter); 
    } 

    #endregion // ICommand Members 
} 

然后创建您的视图模型的属性。例如:

public class YourViewModel 
{ 
    public RelayCommand YourCommand { get; set; } 
    public YourViewModel() 
    { 
     YourCommand = new RelayCommand(DoSmth, CanDoSmth); 
    } 

    private void DoSmth(object obj) 
    { 
     Message.Box("Hello from viewModel"); 
    } 

    private bool CanDoSmth(object obj) 
    { 
     //you could implement your logic here. But by default it should be 
     //set to true 
     return true; 
    } 
} 

和XAML应该是这样的:

<Button Content="Click me!" Command="{Binding YourCommand}"/> 

要获得MVVM认识时,我建议你阅读雷切尔林的博客。她有天赋教人,她可以用简单的条件解释。 Read Rachel Lim's blog. 结识MVVM命令see that post

+0

命令功能实际上存在于我的控制之内。我如何正确地设置? – JokerMartini

+0

我不认为这完全回答了这个问题。 – JokerMartini

+0

@JokerMartini是MVVM还是代码隐藏应用程序? – StepUp