如何在WPF(MVVM)中接收对控件的引用?

时间:2011-04-08 13:41:11

标签: wpf mvvm reference

在我的WPF MVVM项目中,我有一个按钮,它触发一个函数,该函数应该将节点添加到xml,然后将焦点设置为文本框。 我的问题是,我怎样才能收到对控件的引用?

查看:

<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 个答案:

答案 0 :(得分:4)

不要在ViewModel中执行此操作。 ViewModel不应该知道关于视图的任何

您可以在代码隐藏中执行此操作:

  • 处理代码隐藏中的TreeView.SelectedItemChanged事件,并更新ViewModel上的SelectedItem属性(您也可以使用附加行为执行此操作)

  • 关注TextBox,从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);

}

<强>代码隐藏:

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

答案 1 :(得分:1)

您可以使用FocusManager.FocusedElement附加属性来确保TextBox获得焦点。

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

关于你的第二部分(textBox.SelectAll()),你可能需要处理你自己的行为或附属物,它们处理聚焦并一举选择。