【问题标题】:Can I retrieve the User Control from a TreeViewItem?我可以从 TreeViewItem 中检索用户控件吗?
【发布时间】:2011-10-03 10:36:25
【问题描述】:

我有一个绑定到数据的 TreeView(MVVM 模型),我在其中使用用户控件进行数据显示。

        <HierarchicalDataTemplate
          DataType="{x:Type vm:SiteViewModel}" 
          ItemsSource="{Binding Children}">
          <StackPanel Orientation="Horizontal">
             <uc:MyUserControl x:Name="control1" Text="{Binding SiteName}" />
          </StackPanel>
        </HierarchicalDataTemplate>

选择项目后,我需要访问用户控件本身。

我找到了一个与我想要的类似的示例,但它使用了 TreeViewItem.Header。在我的代码中,由于绑定,TreeViewItem.Header 是 SiteViewModel 对象。

有没有一种简单的方法可以从 TreeViewItem 本身检索实际的用户控件(MyUserControl 类型)?

谢谢。

【问题讨论】:

  • 为什么需要访问控件?为什么不能访问控件的视图模型并对其进行修改?
  • 我需要访问控件才能在其上设置属性。用户控件将在显示 TextBlock 和 TextBox 之间切换,以便我可以在 TreeView 中进行“就地”编辑。无论如何,这是计划,但我开始认为这对我来说可能有点先进!也许有更好的方法来实现这一点。
  • 是的,看看 MVVM。这将允许您操纵模型而不是视图本身。视图将通过数据绑定/触发器来响应模型中的变化。
  • 但是,如果做不到这一点,您始终可以使用 LogicalTreeHelper / VisualTreeHelper 在树中挖掘以找到您的 UserControl 实例。

标签: wpf data-binding user-controls treeview


【解决方案1】:

据我了解,您应该指定Command,它将检索或更改某些参数。在您的 xaml 中,它将在您要更改的属性上 Binding,可能带有或不带有转换器。这种方式类似于 MVVM。如果要更改两个控件之间的可见性,例如在您的情况下是 TextBox 和 TextBlock,则应在 View-Model 中创建一个 Visibility 变量,该变量将表示其可见性,并将其值绑定到 TextBox 或 TextBlok。您的 xaml 将包含以下几行:

<Window.Resources>
    <local:ReverseVisibilityConverter  />
</Window.Resources>
 ....
<TextBox Name="MyTB" Visibility="{Binding tbVisibility}" />
<TextBlock Visibility="{Binding ElementName=MyTB, Path=Visibility, Converter={StaticResources ReverseVisibilityConverter }}" />




public sealed class ReverseVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            var flag = (Visibility)value;
            if (flag == Visibility.Visible)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }
        catch
        {
            return Visibility.Visible;
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        try
        {
            if (((Visibility)value) == Visibility.Visible)
                return Visibility.Collapsed;
            else
                return Visibility.Visible;
        }
        catch
        {
            return Visibility.Visible;
        }
    }
}

其中local 是您的Converter 定义的命名空间。您已经指出,tbVisibility - 是变量,存在于Ancestor DataContext 中。如果不清楚,请给我更多信息以帮助您。

【讨论】:

  • 非常感谢。我现在可以通过使用 VisualTreeHelper 检索用户控件(感谢 Kent)来实现它,但我可能会在某个时候重新访问它以获得更简洁的解决方案。
  • 我现在也尝试过这种方法,就像之前的“用户控件”实现一样,当我向 TreeView 添加新项目时,我无法访问新的 TreeViewItem 或用户控件本身将其设置为“编辑”模式。使用这个版本,它在这方面工作得更好一些,但我想选择所有文本并在添加新项目后将焦点设置到 TextBox。到目前为止,我对此的研究只是向我表明这可能非常棘手。有没有一种简单的方法可以做到这一点?
  • 简单的方法,但不是MVVM 之类的,是处理事件SelectedItemChangedMSDN 说,OnItemsChangedprotected。如果你想访问它,你需要从 wpf TreeView 派生你的OwnTreeViewHere 是一篇关于行为和 TreeView 的好文章。
  • 我会调查的。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-24
  • 2010-11-14
  • 1970-01-01
  • 2017-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多