2016-03-08 42 views
0

我想在WPF中編寫一個可用於多個地方的命令,這些地方將對文本框中的文本執行操作。假設命令的目的是在Bold的某些文字上加上星號。該命令將被添加到上下文菜單並定位文本框。可以訪問其目標的WPF命令

這裏有問題:

  • 我怎麼知道被作爲搜索目標文本? ICommand不包含CommandTarget。

  • 如何響應文本框中的更改(例如,如果有任何文本被選中或不是)以便提出CanExecuteChanged?我知道我可以使用CommandManager.RequerySuggested事件,但是有沒有更高效的方法?

這裏是我想象中的XAML看起來:

<TextBox Name="TargetTextBox"> 
     <TextBox.ContextMenu> 
      <ContextMenu> 
       <MenuItem Header="Bold" Command="{x:Static Commands.MyBoldCommand}" CommandTarget="{Binding ElementName=TargetTextBox}" /> 
      </ContextMenu> 
     </TextBox.ContextMenu> 
    </TextBox> 
+0

爲了您的你可以使用MultiBinding參數 – XAMlMAX

+0

如何使用CommandParamter來傳入TextBox?或者,你可以獲得MenuItem附加到的ContextMenu,並檢查它是否是PlacementTarget來獲取它附加的項目 – Rachel

回答

1

你可以通過在使其通過CommandParameter訪問fontWeight設置。下面是一個例子:

XAML:

<TextBox> 
    <TextBox.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Bold" Command="{Binding MyCommand}" CommandParameter="{Binding Path=PlacementTarget.FontWeight, RelativeSource={RelativeSource AncestorType=ContextMenu}}" /> 
     </ContextMenu> 
    </TextBox.ContextMenu> 
</TextBox> 

的ICommand:

public ICommand MyCommand 
{ 
    get 
    { 
     if (_MyCommand == null) 
     { 
      _MyCommand = new RelayCommand(
       param => this.MyCommandFunction(param) 
       ); 
     } 
     return _MyCommand; 
    } 
} 

MyCommandFunction:

private void MyCommandFunction(object param) 
{ 
    FontWeight fw = (FontWeight)param; 
    fw = FontWeights.Bold; 
} 

我只用了一個RelayCommand,但是如果你喜歡,你可以使用DelegateCommand。你必須綁定Command參數,這樣菜單項的datacontext在文本框上有一個可視化。在正常範圍內,它沒有。您仍然需要更新視圖。

0

下面是我用我一般CommandBase什麼從ICommand的繼承:

/// <summary> 
/// Base class for all Commands. 
/// </summary> 
public abstract class CommandBase : ICommand 
{ 
    /// <summary> 
    /// Defines the method that determines whether the command can execute in its current 
    /// state. 
    /// </summary> 
    /// <param name="parameter">Data used by the command. If the command does not require data 
    /// to be passed, this object can be set to null.</param> 
    /// <returns> 
    /// true if this command can be executed; otherwise, false. 
    /// </returns> 
    public virtual bool CanExecute(object parameter) 
    { 
     return true; 
    } 

    /// <summary> 
    /// Defines the method to be called when the command is invoked. 
    /// </summary> 
    /// <param name="parameter">Data used by the command. If the command does not require data 
    /// to be passed, this object can be set to null.</param> 
    public abstract void Execute(object parameter); 

    /// <summary> 
    /// Occurs when changes occur that affect whether or not the command should execute. 
    /// </summary> 
    public event EventHandler CanExecuteChanged 
    { 
     add { CommandManager.RequerySuggested += value; } 
     remove { CommandManager.RequerySuggested -= value; } 
    } 
} 

這裏是我建議的步驟如下:

  1. 在你的視圖模型指定的字符串屬性(MyTextProperty)處理文本框文本。
  2. 創建命令(MyTextChangedCommand),其從上述CommandBase即把你的視圖模型類型(YourViewModelType)的參數繼承。然後通過訪問傳遞給您的命令的ViewModel直接與您的MyTextProperty進行交互,而不是嘗試使用CommandParameters。
  3. 創建類型MyTextChangedCommand在您的視圖模型的屬性,並確保實例它在你的視圖模型的構造。

對於您的命令在WPF結合我會用Blend Interactivity for WPF v4.0

這裏是你將如何實現你的文本框(假設你參考Microsoft.Expression.Interactions爲「我」:

<TextBlock Text="{Binding Path=MyTextProperty"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="LostFocus"> 
      <i:InvokeCommandAction 
       Command="{Binding Path=MyTextChangedCommand}" 
       CommandParameter="Whatever" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
</TextBlock>