简体   繁体   English

在后面的代码中键绑定到 function? WPF/MVVM

[英]KeyBinding to a function in code behind? WPF/MVVM

I have a TextBox, when user presses Enter on their keyboard the value in textbox gets "confirmed" and the string is formatted to the correct amount of decimals.我有一个文本框,当用户在键盘上按 Enter 键时,文本框中的值得到“确认”,并且字符串被格式化为正确的小数位数。

So if the textbox should have 1 decimal and the user writes "30" without any decimals and presses Enter, then the textbox is automatically updated to "30.0".因此,如果文本框应该有 1 位小数,并且用户输入“30”而没有任何小数并按 Enter,那么文本框会自动更新为“30.0”。

The problem is that the CaretIndex is placed at positon 0 when this happens.问题是发生这种情况时 CaretIndex 位于位置 0。 If i press enter with the Caret after 0 like "30|"如果我在 0 之后使用插入符号按 Enter,例如“30 |” then it gets reset to "|30.0" instead of "30.0|"然后它被重置为“|30.0”而不是“30.0|” how i want it.我想要它。

I have a command that gets fired when enter is pressed inside the textbox.我有一个在文本框中按下回车键时触发的命令。 However, the command is inside the View Model, and i should not be touching View things (the caret) inside View Model.但是,该命令位于 View Model 内,我不应该在 View Model 内触摸 View things(插入符号)。 So how should i go on about doing it?那么我应该怎么做呢?

I was thinking of instead of binding to a command in view model i bind to a function in view (code behind) and from that function i raise the command in VM and set caret, like so:我正在考虑而不是绑定到视图 model 中的命令,而是绑定到视图中的 function(代码后面)并从该 function 中引发命令,例如:

    private void EnterPressed()
    {
        ((ParamTextNodeVM)DataContext).EnterCmd.Execute(null);
        ValueBox.CaretIndex = ValueBox.Text.Length;
    }

However, this does not work:但是,这不起作用:

   <TextBox>
       <TextBox.InputBindings>
           <KeyBinding Key="Enter" Command="{Binding EnterPressed}"/>
       </TextBox.InputBindings>
    </TextBox>

How do i bind "Command" to "EnterPressed" that is inside code behind?如何将“Command”绑定到后面代码中的“EnterPressed”?

Binding to a function in the code behind would work, but would violate the MVVM pattern.在后面的代码中绑定到 function 会起作用,但会违反 MVVM 模式。 A relay command allows you to bind a command in the view to the view model.中继命令允许您将视图中的命令绑定到视图 model。

 /// <summary>
/// A basic command that runs an Action
/// </summary>
public class RelayCommand : ICommand
{
    #region Private Members

    /// <summary>
    /// The action to run
    /// </summary>
    private Action mAction;

    #endregion

    #region Public Events

    /// <summary>
    /// The event thats fired when the <see cref="CanExecute(object)"/> value has changed
    /// </summary>
    public event EventHandler CanExecuteChanged = (sender, e) => { };

    #endregion

    #region Constructor

    /// <summary>
    /// Default constructor
    /// </summary>
    public RelayCommand(Action action)
    {
        mAction = action;
    }

    #endregion

    #region Command Methods

    /// <summary>
    /// A relay command can always execute
    /// </summary>
    /// <param name="parameter"></param>
    /// <returns></returns>
    public bool CanExecute(object parameter)
    {
        return true;
    }

    /// <summary>
    /// Executes the commands Action
    /// </summary>
    /// <param name="parameter"></param>
    public void Execute(object parameter)
    {
        mAction();
    }

    #endregion
}

Within the view model itself, you will need to declare the command as a parameter在视图 model 本身中,您需要将命令声明为参数

public ICommand EnterPressedCommand { get; set; }

Finally, within the constructor of the ViewModel, you will need to assign the command to a function最后,在 ViewModel 的构造函数中,您需要将命令分配给 function

EnterPressedCommand = new RelayCommand(() => EnterPressed());

This should allow the command to be triggered from the view, and execute your EnterPressed method这应该允许从视图触发命令,并执行您的 EnterPressed 方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM