0

在过去的几周里,我一直试图让 EditableTextBlock(来自codeproject)在我的 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;
}

对于这三个类中的每一个,都有一个HierarchicalDataTemplate定义MainWindow.Resources如下:

<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有键,因此它会自动应用。

MenuItem单击 的上下文菜单的重命名时触发的事件,C定义如下:

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

问题是当属性设置为 true 在选择重命名的实例上时,EditableTextBlock不会变成 a 。TextBoxIsRenamingC

EditableTextBlock我将它作为普通控件放置时,效果很好。

我的猜测是它与虚拟化有关。任何帮助,将不胜感激。

谢谢你的时间,最好的问候,

100GPing100。

4

1 回答 1

1

class 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 开发有很大帮助。

于 2013-06-25T21:06:34.787 回答