2011-04-08 18 views
2

在我的WPF MVVM項目中,我有一個按鈕觸發一個函數,該函數應該將節點添加到xml,然後將焦點設置爲文本框。 我的問題是,我如何獲得對控件的引用?如何接收對WPF(MVVM)中控件的引用?

查看:

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

視圖模型:

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

TreeViews對MVVM不好用,不幸... – Will 2011-04-08 14:02:54

+0

@實際上它們*可以很好地與MVVM一起玩,但它需要一點工作......我使用一個附加的行爲使得它相對容易綁定SelectedItem。請參閱Josh Smith的[本文](http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx) – 2011-04-08 14:11:30

+0

@ThomasLevesque:lurl,使我做了一些工作來獲得其他控件附帶的相同功能開箱即使打得不錯, – Will 2011-04-08 14:31:56

回答

3

不要做它在視圖模型。 ViewModel不應該知道什麼關於視圖。

你可以做到這一點的代碼隱藏:

  • 處理代碼隱藏的TreeView.SelectedItemChanged事件,並更新視圖模型一個SelectedItem屬性(你也可以用附加的行爲做)

  • 聚焦TextBox,從視圖模型引發一個事件並在處理它的代碼隱藏:

視圖模型:

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

很好的例子,幫助我很多,thx! – jwillmer 2011-04-08 15:38:58

1

您可以使用FocusManager.FocusedElement附加屬性來處理確保TextBox接收焦點。

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

關於你的第二部分(textBox.SelectAll()),你可能必須在處理該聚焦和一舉選擇的行爲或你自己的附加屬性的工作。