【问题标题】:How to set value to property from attached dependency property?如何从附加的依赖属性为属性设置值?
【发布时间】:2017-10-05 17:46:46
【问题描述】:

我正在尝试在文本块中显示选定的树视图项目。这是我的 XAML 代码

<Style TargetType="{x:Type TreeViewItem}">
   <Style.Triggers>
     <Trigger Property="IsSelected" Value="true">
       <Setter Property="vm:HLViewModel.SelectedNode" Value="{Binding ElementName="tree",Path=SelectedItem}"/>
     </Trigger>
   </Style.Triggers>
</Style>

这是我试图显示所选项目的文本块

<TextBlock Text="{Binding myText}"/>

我创建了附加的依赖属性,它将在触发 Treeview 的 IsSelected 属性时设置。如何在回调函数中设置 myText 的值?

public class HLViewModel : DependencyObject
    {
        public myText{get;set;}

        public static object GetSelectedNode(DependencyObject obj)
        {
            return (object)obj.GetValue(SelectedNodeProperty);
        }

        public static void SetSelectedNode(DependencyObject obj, object value)
        {
            obj.SetValue(SelectedNodeProperty, value);
        }

        public static readonly DependencyProperty SelectedNodeProperty =
            DependencyProperty.RegisterAttached("SelectedNode", typeof(object), typeof(HLViewModel), new PropertyMetadata("def",SelectedNode_changed));

        private static void SelectedNode_changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            // wanna set of myText property value here
        }

【问题讨论】:

  • myText 是一个实例属性。你在任何地方都有HLViewModel 的实例吗?它在哪里?我没有看到您正在创建的任何地方。什么是“想要的”?
  • 您是否猜测在 TreeViewItem 上设置附加属性会创建定义附加属性的类的实例?事实并非如此。您正在将该属性添加到 TreeViewItem。
  • @EdPlunkett 此代码仅用于测试。我的目标是获取树视图的选定项。需要 TextBlock 来显示在树视图中选择的内容。重复它只是为了测试。我无法在静态函数中设置 myText 值,因为我们不知道 HLViewModel 类的实例。 d 因为 HLViewModel 给出了 null。 d 来自 TreeViewItem。
  • 你为什么使用附加属性?我非常了解 WPF,你所做的对我来说毫无意义。如果要在文本块中显示所选项目,只需执行以下操作:&lt;TextBlock Text="{Binding ElementName=tree,Path=SelectedItem}" /&gt;。我知道你正在测试。我明白那个。但这没关系。代码仍然没有任何意义。
  • @EdPlunkett 我有 Level 类的可观察集合类型,其中有另一个可观察的 Room 集合类型。 TreeView 将 Levels 显示为父级,将其下的房间显示为子级。当我单击级别时,我需要获取它的子级并使用房间的属性进行一些计算并在任何 UI 元素上显示结果。没关系,它是文本框、数据网格或其他东西。

标签: c# wpf xaml treeview dependency-properties


【解决方案1】:

这是让视图模型使用 TreeView 中选定项目的简单方法:

XAML:

    <TreeView
        x:Name="MyTreeView"
        SelectedItemChanged="MyTreeView_SelectedItemChanged"

代码隐藏:

private void MyTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    (DataContext as MyViewModel).SelectedRoomLevelItem = e.NewValue;
}

这是一种更复杂的方法来做同样的事情。此示例演示如何在 WPF 中使用附加属性。注意 setting TreeViewAttached.SelectedItem 不会设置树视图的选中项——如果你想这样做,它是可行的,但很麻烦。所有此附加属性确实允许您在选择更改时从TreeView中编写接收 Em>所选项目的绑定。

public static class TreeViewAttached
{
    #region TreeViewAttached.SelectedItem Attached Property
    public static Object GetSelectedItem(TreeView obj)
    {
        return (Object)obj.GetValue(SelectedItemProperty);
    }

    public static void SetSelectedItem(TreeView obj, Object value)
    {
        obj.SetValue(SelectedItemProperty, value);
    }

    public static readonly DependencyProperty SelectedItemProperty =
        DependencyProperty.RegisterAttached("SelectedItem", typeof(Object), typeof(TreeViewAttached),
            new FrameworkPropertyMetadata(null) {
                BindsTwoWayByDefault = true
            });
    #endregion TreeViewAttached.SelectedItem Attached Property

    #region TreeViewAttached.MonitorSelectedItem Attached Property
    public static bool GetMonitorSelectedItem(TreeView obj)
    {
        return (bool)obj.GetValue(MonitorSelectedItemProperty);
    }

    public static void SetMonitorSelectedItem(TreeView obj, bool value)
    {
        obj.SetValue(MonitorSelectedItemProperty, value);
    }

    public static readonly DependencyProperty MonitorSelectedItemProperty =
        DependencyProperty.RegisterAttached("MonitorSelectedItem", typeof(bool), typeof(TreeViewAttached),
            new PropertyMetadata(false, MonitorSelectedItem_PropertyChanged));

    private static void MonitorSelectedItem_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            (d as TreeView).SelectedItemChanged += TreeViewAttached_SelectedItemChanged;
        }
        else
        {
            (d as TreeView).SelectedItemChanged -= TreeViewAttached_SelectedItemChanged;
        }
    }

    private static void TreeViewAttached_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    {
        SetSelectedItem(sender as TreeView, e.NewValue);
    }
    #endregion TreeViewAttached.MonitorSelectedItem Attached Property
}

XAML:

<TreeView
    local:TreeViewAttached.MonitorSelectedItem="True"
    local:TreeViewAttached.SelectedItem="{Binding SelectedRoomLevelItem}"
    ItemsSource="{Binding Items}"
    >
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Items}">
            <Label Content="{Binding HeaderText}" />
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
<Label Content="{Binding Path=SelectedRoomLevelItem.HeaderText}" />

我的示例使用具有ItemsHeaderText 属性的快速树视图项数据上下文类。您对该代码的使用必须适应项目中特定的视图模型类。

【讨论】:

    猜你喜欢
    • 2014-08-14
    • 2020-12-22
    • 2012-06-01
    • 2015-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多