问题
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.SelectedItemChangedevent in code-behind, and update aSelectedItemproperty 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