How can i receive a reference to a control in WPF

2019-07-17 03:44发布

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();
}

2条回答
相关推荐>>
2楼-- · 2019-07-17 03:57

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();
}
查看更多
狗以群分
3楼-- · 2019-07-17 04:07

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.

查看更多
登录 后发表回答