WPF将DependencyProperty绑定到另一个DependencyProperty

时间:2017-03-24 17:08:59

标签: c# wpf treeview

我在UserControl中有一个TreeView,它可以滚动+缩放和拖动。 (因为TreeView非常庞大)因为Scroll / Zoom / Drag UserControl正在监听

  1. OnScrollViewerScrollChanged
  2. OnMouseLeftButtonUp
  3. OnMouseLeftButtonUp
  4. OnPreviewMouseWheel
  5. OnMouseLeftButtonDown
  6. 的OnMouseMove
  7. TreeViewItems无法接收任何鼠标输入。因此,我为TreeViewItem创建了一个DependencyProperty,所​​谓的IsMouseHover。如果鼠标进入或离开TreeViewItem,则DP在true和false之间切换。

    ScrollZoomDrag UserControl还有一个DP,所谓的“Active”,它订阅或取消订阅上面提到的所有事件。

    现在我想将TreeViewItem的“IsMouseHover”绑定到ScrollZoomDrag的Control“Active”DP。

        <controls:ScrollDragZoomControl>
        <controls:OrgTreeView ItemsSource="{Binding Root}">
            <controls:OrgTreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=TwoWay}">
                    <controls:VisualElement DataContext="{Binding}">
                        <Style TargetType="controls:ScrollDragZoomControl">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=controls:VisualElement}, Path=IsMouseHover}" Value="True">
                                    <Setter Property="Active" Value="False" />
                                </DataTrigger>
                                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=controls:VisualElement}, Path=IsMouseHover}" Value="False">
                                    <Setter Property="Active" Value="True" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </controls:VisualElement>
                </HierarchicalDataTemplate>
            </controls:OrgTreeView.ItemTemplate>
        </controls:OrgTreeView>
    </controls:ScrollDragZoomControl>
    

    使用上面的解决方案,ScrollZoomDrag的DP“Active”根本不会切换。我错过了什么或者有更好的方法吗?

    更新

    ScrollZoomDrag.xaml.cs

            public static readonly DependencyProperty ActiveProperty = DependencyProperty.Register("Active", typeof(bool), typeof(ScrollDragZoomControl), new PropertyMetadata(true, new PropertyChangedCallback(ActiveChanged)));
    
        public bool Active
        {
            get { return (bool)GetValue(ActiveProperty); }
            set { SetValue(ActiveProperty, value); }
        }
    
        public static void ActiveChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            ScrollDragZoomControl scrollDragZoomControl = (ScrollDragZoomControl)obj;
    
            if ((bool)args.NewValue)
                scrollDragZoomControl.StartListen();
            else scrollDragZoomControl.StopListen();
        }
    

    VisualElement.xaml.cs

            public static readonly DependencyProperty IsMouseHoverProperty = DependencyProperty.Register("IsMouseHover", typeof(bool), typeof(VisualElement), new PropertyMetadata(false));
    
        public VisualElement()
        {
            InitializeComponent();
            MouseEnter += VisualElement_MouseEnter;
            MouseLeave += VisualElement_MouseLeave;
        }
    
        public bool IsMouseHover
        {
            get { return (bool)GetValue(IsMouseHoverProperty); }
            set { SetValue(IsMouseHoverProperty, value); }
        }
    
        private void VisualElement_MouseLeave(object sender, MouseEventArgs e)
        {
            IsMouseHover = false;
        }
    
        private void VisualElement_MouseEnter(object sender, MouseEventArgs e)
        {
            IsMouseHover = true;
        }
    

    方法2 :(也不起作用)

        <controls:ScrollDragZoomControl>
        <controls:ScrollDragZoomControl.Style>
            <Style TargetType="controls:ScrollDragZoomControl">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType=controls:VisualElement}, Path=IsMouseHover}" Value="True">
                        <Setter Property="Active" Value="False" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </controls:ScrollDragZoomControl.Style>
        <controls:OrgTreeView ItemsSource="{Binding Root}"
                              HorizontalAlignment="Center"
                              VerticalAlignment="Center">
            <controls:OrgTreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=TwoWay}">
                    <controls:VisualElement DataContext="{Binding}">                   
                    </controls:VisualElement>
                </HierarchicalDataTemplate>
            </controls:OrgTreeView.ItemTemplate>
        </controls:OrgTreeView>
    </controls:ScrollDragZoomControl>
    

2 个答案:

答案 0 :(得分:1)

尝试与Mode=OneWayToSource绑定:

IsMouseHover="{Binding RelativeSource={RelativeSource AncestorType=controls:ScrollDragZoomControl}, 
                       Path=Active, Mode=OneWayToSource}"
<controls:ScrollDragZoomControl>
  <controls:OrgTreeView ItemsSource="{Binding Root}">
    <controls:OrgTreeView.ItemTemplate>
       <HierarchicalDataTemplate ItemsSource="{Binding Children, Mode=TwoWay}">
         <controls:VisualElement DataContext="{Binding}" 
             IsMouseHover="{Binding RelativeSource={RelativeSource AncestorType=controls:ScrollDragZoomControl}, 
                                    Path=Active, Mode=OneWayToSource}">
         </controls:VisualElement>
      </HierarchicalDataTemplate>
    </controls:OrgTreeView.ItemTemplate>
  </controls:OrgTreeView>
</controls:ScrollDragZoomControl>

答案 1 :(得分:0)

可能默认设置Active属性绑定TwoWay,以便它可以注册每个更改

new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

我不确定,但是通知更改可能会有所帮助,或者您需要在xaml mode=TwoWay

中设置它