首页 文章

wpf TreeViewItem BringIntoView并不总是有效

提问于
浏览
2

在我的MVVM应用程序中,我有一个树视图,应该在选择时将treeviewitem带入视图 . 树视图表示数据库中的记录 . 每个树视图项目在选中时通过展开项目来按需加载其子项 .

树视图样式定义如下:

<TreeView.ItemContainerStyle>
    <Style TargetType="{x:Type TreeViewItem}">
      <Setter Property="OverridesDefaultStyle" Value="True"/>
      ...
      <EventSetter Event="Selected" Handler="OnTreeViewItemSelected"/>

处理程序的定义如下:

private void OnTreeViewItemSelected(object sender, RoutedEventArgs e)
{
  if (!Object.ReferenceEquals(sender, e.OriginalSource))
  {
    return;
  }
  TreeViewItem item = e.OriginalSource as TreeViewItem;
  if (item != null)
  {        
    EventHandler eventHandler = null;
    eventHandler = new EventHandler(delegate
    {
      treeData.LayoutUpdated -= eventHandler;
      item.BringIntoView();
    });
    treeData.LayoutUpdated += eventHandler;
  }
}

这适用于已加载的项目 .

[编辑:实际上必须扩展所选项目的父项而不是仅加载]

如果它们被加载,则迭代treeviewitems直到找到所寻找的项目,选择找到的项目并且上面的处理程序成功地将其带入视图 .

问题在于尚未加载的项目 . 在这些情况下,我的代码获取所搜索项目的祖先记录,遍历它们扩展项目(因此加载子项)直到它到达所寻找的项目 . 这是成功选择的,但不会被带入视野 .

有谁知道如何解决这个问题?

[更新]在TreeViewItemViewModel中:

public bool IsSelected
{
  get { return _isSelected; }
  set
  {        
    if (value != _isSelected)
    {          
      _isSelected = value;

      if (value == true)          
        IsExpanded = value;          

      this.OnPropertyChanged("IsSelected");
    }
  }
}

public bool IsExpanded
{
  get { return _isExpanded; }
  set
  {
    if (_isExpanded == value)
      return;

    _isExpanded = value;
    this.OnPropertyChanged("IsExpanded");

    if (_isExpanded && 
        _parent != null &&
        _parent.IsExpanded == false)
      _parent.IsExpanded = true;

    LoadChildren();
  }
}

LoadChildren()方法通过使用标志来处理子项是否需要加载 .

ItemContainerStyle

Setter Property =“IsExpanded”Value =“{Binding IsExpanded,Mode = TwoWay}”Setter Property =“IsSelected”Value =“{Binding IsSelected,Mode = TwoWay}”

2 回答

  • 3

    this可能会解决您的问题

    并构建于this关于将MVVM用于TreeView的文章

    编辑:还有可能你的treeviewitemcontainers尚未创建 . 然后你必须摆弄TreeViews ItemContainerGenerator

  • 0

    好吧,所以我似乎已经通过“意外”解决了这个问题 .

    如果我在后台进程中运行搜索,则将其置于视图中

    public void Search()
    {
      ImplementSearch();
    
      _workinghelper = new WorkingHelper();
      SearchWorkingViewModel searchvm = new SearchWorkingViewModel(_workinghelper.WorkingWindow);
      VisualUtils.FadeTreeViewItemViewModel(1.0, 0.2, 0, 100);
      _workinghelper.MakeWorking(searchvm);
    
      VisualUtils.FadeTreeViewItemViewModel(0.2, 1.0, 0, 001);
    }
    
    public bool CanSearch
    {
      get { return _searchlogic.SearchTypeIsValid(_searchterm); }
    }
    
    void ImplementSearch()
    {      
      BackgroundTaskManager.RunBackgroundTask(
        () =>
        {
          bool run_success = _searchlogic.PerformSearch(_searchterm);
          Thread.Sleep(500);
          return run_success;
        },
        (run_success) =>
        {
          if (run_success == false)
            ApplicationSetup.DisableApp((MainWindow)App.Current.MainWindow, "The search function has caused an unexpected internal error. Please contact an administrator for help.");
    
          if (_workinghelper != null)
            _workinghelper.DisposeWorkingWindow();
        });      
    }
    

    但是,如果我只是运行bool run_success = _searchlogic.PerformSearch(_searchterm);在ImplementSearch()中,项目不会被带入视图 .

相关问题