【问题标题】:Change propery of control, that has a TwoWay binding更改具有双向绑定的控件属性
【发布时间】:2021-01-31 03:05:12
【问题描述】:

我有一个带有 bool 属性的自定义控件。该属性绑定了包含模板控件和弹出窗口。

XAML 控件:

<controls:AutoCompleteTextBox x:Name="PART_Editor"
                              IsEnabled="False"
                              IsPopupOpen="{Binding IsAutocompletePopupOpen}" />

控件中的属性:

        public bool IsPopupOpen
        {
            get => (bool)GetValue(IsPopupOpenProperty);
            set => SetValue(IsPopupOpenProperty, value);
        }

        public static readonly DependencyProperty IsPopupOpenProperty =
            DependencyProperty.Register("IsPopupOpen", typeof(bool), typeof(AutoCompleteTextBox), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

绑定到模板控件中包含的元素:

<Popup x:Name="PART_AutoCompletePopup"
       IsOpen="{Binding IsPopupOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" />

我需要在点击时更改属性 IsPopupOpen。我决定在行为上这样做,但我需要禁用我的控制。因此我将行为添加到控制容器

<Grid>
    <controls:AutoCompleteTextBox x:Name="PART_Editor"
                                  IsEnabled="False"
                                  IsPopupOpen="{Binding IsAutocompletePopupOpen}"/> 
    <i:Interaction.Behaviors>
        <behaviors:PopupContainerBehavior IsPopupOpen="{Binding IsAutocompletePopupOpen, Mode=TwoWay}" />
    </i:Interaction.Behaviors>
</Grid>

行为代码:

public class PopupContainerBehavior : Behavior<UIElement>
    {
        public bool IsPopupOpen
        {
            get { return (bool)GetValue(IsPopupOpenProperty); }
            set { SetValue(IsPopupOpenProperty, value); }
        }

        public static readonly DependencyProperty IsPopupOpenProperty =
            DependencyProperty.Register("IsPopupOpen", typeof(bool), typeof(PopupContainerBehavior), new PropertyMetadata(false));


        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.PreviewMouseLeftButtonDown += OnMouseLeftButtonUp;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            AssociatedObject.PreviewMouseLeftButtonDown -= OnMouseLeftButtonUp;
        }

        private void OnMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            IsPopupOpen = true;
        }
    }

问题是属性先变为true,然后立即变为false。通过SNOOP可以通过属性的闪烁值看到这一点。我认为问题在于TwoWay Binding,但我不知道如何修复它

【问题讨论】:

    标签: c# .net wpf mvvm binding


    【解决方案1】:

    发生这种情况的原因是由于鼠标捕获。

    • 行为的PreviewMouseLeftButtonDown 事件处理程序告诉Popup 打开
    • Popup 捕获鼠标
    • 容器的其余点击事件触发
    • 容器从Popup 中删除鼠标捕获
    • Popup 立即关闭

    这可能是一个很难解决的问题。

    您可能需要考虑让您的控件能够在 Popup 被禁用时打开它,而不是尝试从外部打开它。即使某个控件被禁用,您也可以通过在需要交互的部分上设置IsHitTestVisible 等来使其部分可点击。

    【讨论】:

      猜你喜欢
      • 2023-03-26
      • 2021-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-20
      相关资源
      最近更新 更多