2013-06-25 67 views
0

在過去的幾個星期裏,我一直試圖讓我的TreeView工作的EditableTextBlock(從codeproject)。EditableTextBlock - TreeView - 虛擬化

該控件的屬性IsInEditMode設置爲true時將其更改爲TextBox

TreeView是虛擬化,並聲明如下:

<TreeView x:Name="treeEnvironment" 
      Margin="0,29,0,0" BorderThickness="0" 
      VirtualizingStackPanel.IsVirtualizing="True" 
      VirtualizingStackPanel.VirtualizationMode="Recycling"> 
</TreeView> 

TreeView使用ItemsSource屬性來獲取它的數據並在此值始終是類的一個實例(可以稱之爲A)。這個類包含另一種類型的實例列表(我們稱之爲B)。最後一個類包含另一個類的實例列表(我們稱之爲「C」)。這是怎麼看起來像在代碼:

class A 
{ 
     public String Name; 
     public ObservableCollection<B> Items; 
} 

class B 
{ 
     public String Name; 
     public ObservableCollection<C> Items; 
} 

class C 
{ 
     public String Name; 
     public bool IsRenaming; 
} 

對於這三個班的存在MainWindow.Resources定義如下的HierarchicalDataTemplate

<DataTemplate DataType="{x:Type C}"> 
    <StackPanel Orientation="Horizontal"> 
     <StackPanel.ContextMenu> 
      <ContextMenu> 
       <MenuItem Header="Rename" Click="C_Rename_Click" /> 
      </ContextMenu> 
     </StackPanel.ContextMenu> 

     <v:EditableTextBlock Text="{Binding Path=Name}" IsInEditMode="{Binding Path=IsRenaming, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
    </StackPanel> 
</DataTemplate> 

<HierarchicalDataTemplate DataType="{x:Type B}" ItemsSource="{Binding Path=Items, Mode=OneWay}"> 
    <StackPanel Orientation="Horizontal"> 
     <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Name}" /> 
    </StackPanel> 
</HierarchicalDataTemplate> 

<HierarchicalDataTemplate DataType="{x:Type A}" ItemsSource="{Binding Path=Items, Mode=OneWay}"> 
    <StackPanel Orientation="Horizontal"> 
     <Image Source="icons/icon_A.png" Width="16" Height="16" /> 
     <TextBlock Text="{Binding Path=Name}" ToolTip="{Binding Path=Name}" /> 
    </StackPanel> 
</HierarchicalDataTemplate> 

DataTemplate都沒有鑰匙,使其自動應用。

點擊C的上下文菜單中的重命名MenuItem時,則觸發事件,定義如下:

private void C_Rename_Click(object sender, RoutedEventArgs e) 
{ 
    C instance = (sender as FrameworkElement).DataContext as C; 

    if (instance != null) { 
     instance.IsRenaming = true; 
    } else { 
     MessageBox.Show("DEBUG: C_Rename_Click(" + sender.ToString() + ", " + e.ToString() + ") : instance == null"); 
    } 
} 

的問題是,EditableTextBlock不會變成一個TextBoxIsRenaming財產在選擇要重命名的實例C上設置爲true。

EditableTextBlock工作得很好,當我把它作爲一個正常的控制。

我的猜測是它與虛擬化有關。任何幫助,將不勝感激。

謝謝你的時間,最好的問候,

100GPing100。

回答

1

A,B,C需要實現INotifyPropertyChanged對它們進行的任何更改都要傳播到UI。你可以在每個類中分別實現它,或者讓一個基類實現INPC並從這個基類派生你的類。

喜歡的東西:

public class MyBaseViewModel : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) { 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (handler != null) 
     handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

public class A : MyBaseViewModel { 
    private string _name; 
    public string Name { 
    get { 
     return _name; 
    } 
    set { 
     _name = value; 
     OnPropertyChanged("Name"); 
    } 
    } 

    private ObservableCollection<B> _items; 
    public ObservableCollection<B> Items { 
    get { 
     return _items; 
    } 
    set { 
     _items = value; 
     OnPropertyChanged("Items"); 
    } 
    } 
} 

public class B : MyBaseViewModel { 
    private string _name; 
    public string Name { 
    get { 
     return _name; 
    } 
    set { 
     _name = value; 
     OnPropertyChanged("Name"); 
    } 
    } 

    private ObservableCollection<C> _items; 
    public ObservableCollection<C> Items { 
    get { 
     return _items; 
    } 
    set { 
     _items = value; 
     OnPropertyChanged("Items"); 
    } 
    } 
} 

public class C : MyBaseViewModel { 
    private string _name; 
    public string Name { 
    get { 
     return _name; 
    } 
    set { 
     _name = value; 
     OnPropertyChanged("Name"); 
    } 
    } 

    private bool _isRenaming; 
    public bool IsRenaming { 
    get { 
     return _isRenaming; 
    } 
    set { 
     _isRenaming = value; 
     OnPropertyChanged("IsRenaming"); 
    } 
    } 
} 

現在,當你在你的代碼更改IsRenaming,你會看到更新傳播到UI和TextBlock切換到TextBox

側面說明

請看看MVVM。如果你不確定。慢慢學習吧,它有助於WPF中的UI開發。

+0

謝謝,這有助於很多,不僅有這個問題,而且讓我更好地理解MVVM。欣賞它:D – zeluisping