我有一種情況,我想爲框架元素編寫自定義命令。 這是我喜歡做如下:自定義附加命令
public class UndoRedoManager
{
private static FrameworkElement frameworkElement;
/// <summary>
/// UndoVMCommand Attached properrty.
/// </summary>
public static readonly DependencyProperty UndoVMCommandProperty =
DependencyProperty.RegisterAttached("UndoVMCommand", typeof(ICommand), typeof(UndoRedoManager), new FrameworkPropertyMetadata(UndoVmCommand, UndoVMCommand_PropertyChanged));
/// <summary>
/// UndoVMCommandProperty getter.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
[AttachedPropertyBrowsableForChildren]
public static ICommand GetUndoVMCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(UndoVMCommandProperty);
}
/// <summary>
/// UndoVMCommandProperty setter.
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetUndoVMCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(UndoVMCommandProperty, value);
}
protected static void UndoVMCommand_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var control = obj as FrameworkElement;
if (control != null)
{
if ((e.NewValue != null) && (e.OldValue == null))
{
frameworkElement = control;
}
else if ((e.NewValue == null) && (e.OldValue != null))
{
frameworkElement = null;
}
}
}
}
這個我在XAML從而連接:
<ItemsControl x:Name="graphControl" local:UndoRedoManager.UndoVMCommand="{Binding UndoCommand}">
......
</ItemsControl>
不過,我想點擊一個按鈕啓動此命令。
<Button Content="Undo" CommandTarget="{Binding ElementName=graphControl}" Command="TheCommand" Margin="5"/>
非常喜歡
<Button Command="Copy" CommandTarget="{Binding ElementName=MyTextBox1}">Copy</Button>
所以我寫了下面的:
public static RoutedUICommand undoVmCommand = new RoutedUICommand("TheCommand", "TheCommand", typeof(UndoRedoManager));
public static RoutedUICommand UndoVmCommand
{
get { return undoVmCommand; }
}
static UndoRedoManager()
{
CommandManager.RegisterClassCommandBinding(typeof(UndoRedoManager), new CommandBinding(undoVmCommand, ExecutedEventHandler_UndoVM, CanExecuteEventHandler_IfCanUndoVM));
}
private static void CanExecuteEventHandler_IfCanUndoVM(Object sender, CanExecuteRoutedEventArgs e)
{
FrameworkElement frmEle = sender as FrameworkElement;
e.CanExecute = false;
if (null != frmEle && frmEle.DataContext is ViewModelBase)
{
e.CanExecute = true;
//(frmEle.DataContext as GraphViewModel).CanUndo;
}
e.Handled = true;
}
public static void ExecutedEventHandler_UndoVM(Object sender, ExecutedRoutedEventArgs e)
{
FrameworkElement frmEle = sender as FrameworkElement;
if (null != frmEle && frmEle.DataContext is ViewModelBase)
{
(frmEle.DataContext as GraphViewModel).UndoCommand.Execute(null);
}
}
我沒有得到它如何連線,。我應該在哪裏聲明上面的路由命令?當然,我不能在FrameworkElement類中做到這一點。有沒有辦法來附加? 對不起,如果我沒有能夠清楚地說明問題。簡單地說: 如果我要以附加方式爲文本框編寫「複製」命令,我該怎麼做?
編輯:@ ERTI的評論後:
現在我有兩個班,UndoRedoManager
public class UndoRedoManager
{
private static FrameworkElement frameworkElement;
/// <summary>
/// UndoVMCommand Attached properrty.
/// </summary>
public static readonly DependencyProperty UndoVMCommandProperty =
DependencyProperty.RegisterAttached("UndoVMCommand", typeof(ICommand), typeof(UndoRedoManager), new FrameworkPropertyMetadata(StaticCommand.UndoVmCommand, UndoVMCommand_PropertyChanged));
/// <summary>
/// UndoVMCommandProperty getter.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
[AttachedPropertyBrowsableForChildren]
public static ICommand GetUndoVMCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(UndoVMCommandProperty);
}
/// <summary>
/// UndoVMCommandProperty setter.
/// </summary>
/// <param name="obj"></param>
/// <param name="value"></param>
public static void SetUndoVMCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(UndoVMCommandProperty, value);
}
protected static void UndoVMCommand_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var control = obj as FrameworkElement;
if (control != null)
{
if ((e.NewValue != null) && (e.OldValue == null))
{
frameworkElement = control;
}
else if ((e.NewValue == null) && (e.OldValue != null))
{
frameworkElement = null;
}
}
}
}
請注意在PropertyMetadata通過在註冊依賴屬性的默認值。 在XAML我使用它作爲:
<ItemsControl x:Name="graphControl" local:UndoRedoManager.UndoVMCommand="{Binding UndoCommand}"/>
另一個是StaticCommand類:
public class StaticCommand
{
public static RoutedUICommand undoVmCommand = new RoutedUICommand("TheCommand", "TheCommand", typeof(UndoRedoManager));
public static RoutedUICommand UndoVmCommand
{
get { return undoVmCommand; }
}
static StaticCommand()
{
CommandManager.RegisterClassCommandBinding(typeof(StaticCommand), new CommandBinding(undoVmCommand, ExecutedEventHandler_UndoVM, CanExecuteEventHandler_IfCanUndoVM));
}
private static void CanExecuteEventHandler_IfCanUndoVM(Object sender, CanExecuteRoutedEventArgs e)
{
//This is not getting hit.
e.CanExecute = true;
e.Handled = true;
}
public static void ExecutedEventHandler_UndoVM(Object sender, ExecutedRoutedEventArgs e)
{
//I will do something here
}
}
在XAML中,我使用它作爲:
<Button Content="Undo" CommandTarget="{Binding ElementName=graphControl}" Command="{Binding Source={x:Static local:StaticCommand.UndoVmCommand}}" Margin="5"/>
但現在上面的按鈕根本沒有被激活。
嗨@Erti謝謝。現在按鈕從未啓用。令我沮喪的是,CanExecuteEventHandler_IfCanUndoVM從未受到影響。我已經編輯了完整圖片的問題。 – James 2013-04-05 08:57:31
嘗試Command =「{x:Static local:StaticCommand.UndoVmCommand}」,而不是綁定它。我更新了我的帖子。 – 2013-04-05 18:20:47