How can i receive a reference to a control in WPF (MVVM)?

依然范特西╮ 提交于 2019-12-24 00:54:36

问题


In my WPF MVVM Project I have a button that triggers a function that should add a node to a xml and then set the focus to a textbox. My question is, how can i receive a reference to a control?

View:

<Button Command="{Binding Path=ButtonAddCategory_Click}" />

ViewModel:

RelayCommand buttonAddCategory_Click;
public ICommand ButtonAddCategory_Click
{
    get
    {
        return buttonAddCategory_Click ?? (buttonAddCategory_Click = new RelayCommand(param => this.AddCategory(),
                                                                                      param => true));
    }
}

public void AddCategory()
{
    ...
    //get the "node" -> reference?
    XmlNode selectedItem = (XmlNode)treeView.SelectedItem;
    ..
    //add the node to the xml
    ..
    //change focus -> reference?
    textBoxTitel.Focus();
    textBoxTitel.SelectAll();
}

回答1:


Don't do it in the ViewModel. The ViewModel shouldn't know anything about the view.

You can do it in code-behind:

  • handle the TreeView.SelectedItemChanged event in code-behind, and update a SelectedItem property on the ViewModel (you could also do it with an attached behavior)

  • to focus the TextBox, raise an event from the ViewModel and handle it in code-behind:

ViewModel:

public XmlNode SelectedItem { get; set; }

public event EventHandler FocusTitle;

public void AddCategory()
{
    ...
    //get the "node" -> reference?
    XmlNode selectedItem = this.SelectedItem;
    ..
    //add the node to the xml
    ..
    // Notify the view to focus the TextBox
    if (FocusTitle != null)
        FocusTitle(this, EventArgs.Empty);

}

Code-behind:

// ctor
public MyView()
{
    InitializeComponent();
    DataContextChanged += MyView_DataContextChanged;
}

private void MyView_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    MyViewModel vm = (MyViewModel)e.NewValue;
    vm.FocusTitle += ViewModel_FocusTitle;
}

private void TreeView1_SelectedItemChanged(object sender, RoutedPropertyChangedEventHandler<Object> e)
{
    MyViewModel vm = (MyViewModel)DataContext;
    vm.SelectedItem = (XmlNode)e.NewValue;
}

private void ViewModel_FocusTitle(object sender, EventArgs e)
{
    textBoxTitle.Focus();
}



回答2:


You could use the FocusManager.FocusedElement attached property to handle ensuring the TextBox receives focus.

<DataTemplate DataType="{x:Type YourViewModel}">
    <Grid FocusManager.FocusedElement="{Binding ElementName=userInput}">
       <TextBox x:Name="userInput" />
    </Grid>
</DataTemplate>

As for your second part (textBox.SelectAll()) you may have to work on a behavior or attached property of your own that handles the focusing and selecting in one fell swoop.



来源:https://stackoverflow.com/questions/5595949/how-can-i-receive-a-reference-to-a-control-in-wpf-mvvm

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!