简体   繁体   English

每次依赖属性设置为 true 时,都不会调用从另一个用户控件绑定到依赖属性的视图模型属性

[英]View model property bound to a dependency property from another user control is never called every time the dependency property is set to true

I have a WPF User Control in which I place another WPF user control.我有一个 WPF 用户控件,我在其中放置了另一个 WPF 用户控件。 Note that I only post the relevant things here to understand it.注意,我这里只贴出相关的东西,方便大家理解。

    <UserControl x:Class="myApp.UI.Views.myMainView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                 xmlns:vm="clr-namespace:myApp.UI.ViewModels"
                 xmlns:v="clr-namespace:myApp.UI"
                 xmlns:p="clr-namespace:myApp.Properties"
                 mc:Ignorable="d"
                 d:DataContext="{d:DesignInstance Type=vm:myMainViewModel}"
                 d:DesignHeight="450" d:DesignWidth="800">
    
            <Button x:Name="myHelpButton"/>

            <v:myAnotherUserControl PlacementTarget="{Binding ElementName=myHelpButton}"
 IsHyperlinkChangedCallback="{Binding Path=IsHyperlinkChangedCallback, Mode=OneWayToSource}" HyperLinkText="{x:Static p:Resources.HyperlinkText}">
            </v:myAnotherUserControl>
    
    </UserControl>

The important thing here you must pay attention is the view model property IsHyperlinkChangedCallback which is bound to a dependency property (which same name) from the myAnotherUserControl user control.此处您必须注意的重要事项是视图模型属性 IsHyperlinkChangedCallback,它绑定到 myAnotherUserControl 用户控件的依赖属性(同名)。 This is set to be OneWayToSource because it is only updated within myAnotherUserControl and I want the main user control myMainView to be notified when this happens and if so to execute the ShowHelp() method (see later in this post) in the view model.这被设置为 OneWayToSource 因为它只在 myAnotherUserControl 中更新,我希望主用户控件 myMainView 在发生这种情况时得到通知,如果是这样,则在视图模型中执行 ShowHelp() 方法(见本文后面)。

Above user control is based on MVVM and its view model associated is the following (only relevant part for this post is shown):上面的用户控件是基于 MVVM 的,其关联的视图模型如下(仅显示与本文相关的部分):

myMainViewModel.cs :我的主视图模型.cs

namespace myApp.UI.ViewModels
{
    public partial class myMainViewModel : ViewModelBase
    {

          bool _isHyperlinkChangedCallback = false;

          // This property is never set from this class! it comes always set from
          // the myAnotherUserControl which is the one who can do it. In this class
          // we only process the notification that comes and proceed accordingly.
          public bool IsHyperlinkChangedCallback
          {
             get => this._isHyperlinkChangedCallback;

             set
             {
                this._isHyperlinkChangedCallback = value;

                if (value)
                {
                   this.ShowHelp();
                }
             }
          }

          private void ShowHelp()
          {
               // Do some stuff here
          }
    }
}

In the myAnotherUserControl I only have an WPF Popup.在 myAnotherUserControl 中,我只有一个 WPF 弹出窗口。 In the WPF Popup below i have some TextBlocks and finally at the bottom an WPF hyperlink (All them within a stackpanel).在下面的 WPF 弹出窗口中,我有一些 TextBlocks,最后在底部有一个 WPF 超链接(它们都在堆栈面板中)。 I only show here the WPF hyperlink (the rest is not necessary for this post):我在这里只显示 WPF 超链接(其余部分对于这篇文章不是必需的):

myAnotherUserControl.xaml :我的另一个用户控件.xaml

<UserControl x:Class="myApp.UI.myAnotherUserControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:local="clr-namespace:myApp.UI"
             mc:Ignorable="d"
             d:DataContext="{d:DesignInstance Type=local:myAnotherUserControl}"
             d:DesignHeight="450" d:DesignWidth="800">
   <Grid>
        <Popup AllowsTransparency="True"                               
               StaysOpen="False"
               Placement="Custom"
               PlacementTarget="{Binding Path=PlacementTarget}">

                <TextBlock Visibility="Visible">
                    <Hyperlink Click="myHyperlink_Click" 
                               TextDecorations="None">
                        <TextBlock Text="{Binding Path=HyperLinkText}"/>                                           
                    </Hyperlink>
                </TextBlock>
        </Popup>
   </Grid>
</UserControl>

In case of myAnotherUserControl, I am not using MVVM, so the code-behind for above myAnotherUserControl.xaml is below.对于 myAnotherUserControl,我没有使用 MVVM,因此上面 myAnotherUserControl.xaml 的代码隐藏在下面。 The myAnotherUserControl has some dependency properties defined. myAnotherUserControl 定义了一些依赖属性。

myAnotherUserControl.xaml.cs :我的另一个用户控件.xaml.cs

namespace myApp.UI
{
    public partial class myAnotherUserControl : UserControl
    {

        public static readonly DependencyProperty IsHyperlinkChangedCallbackProperty =
            DependencyProperty.Register("IsHyperlinkChangedCallback",
                                        typeof(bool),
                                        typeof(myAnotherUserControl),
                                        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public bool IsHyperlinkChangedCallback
        {
            get => (bool)GetValue(IsHyperlinkChangedCallbackProperty );
            set => SetValue(IsHyperlinkChangedCallbackProperty, value);
        }

        public static readonly DependencyProperty HyperLinkTextProperty =
            DependencyProperty.Register("HyperLinkText",
                                        typeof(string),
                                        typeof(myAnotherUserControl),
                                        new FrameworkPropertyMetadata(defaultValue: "Click me!"));

        public string HyperLinkText
        {
            get => (string)GetValue(HyperLinkTextProperty);
            set => SetValue(HyperLinkTextProperty, value);
        }

        public static readonly DependencyProperty PlacementTargetProperty =
            DependencyProperty.Register("PlacementTarget",
                                        typeof(UIElement),
                                        typeof(myAnotherUserControl),
                                        new FrameworkPropertyMetadata(defaultValue: null,
                                            propertyChangedCallback: OnPlacementTargetChanged));

        public UIElement PlacementTarget
        {
            get => (UIElement)GetValue(PlacementTargetProperty);
            set => SetValue(PlacementTargetProperty, value);
        }

        private void myHyperlink_Click(object sender, RoutedEventArgs e)
        {
             // I want to notify to the myMainView in order it can execute the ShowHelp() method when it is true.
             this.IsHyperlinkChangedCallback = true;
        }
    }
}

What's the problem I have?我有什么问题?

When I click on the hyperlink in the Popup, the myHyperlink_Click gets executed, sets the IsHyperlinkChangedCallback to true (it is false previously, I have checked putting a breakpoint there), but the view model property IsHyperlinkChangedCallback is never called (see class myMainViewModel above at the beginning of this post) so method ShowHelp() is not executed.当我单击 Popup 中的超链接时,myHyperlink_Click 被执行,将 IsHyperlinkChangedCallback 设置为 true(之前它是 false,我已经检查过在那里放置断点),但是从未调用视图模型属性 IsHyperlinkChangedCallback(参见上面的 myMainViewModel 类)这篇文章的开头)所以方法 ShowHelp() 没有被执行。 I need ShowHelp() method to be executed each time this.IsHyperlinkChangedCallback is set to true within myHyperlink_Click event handler.每次在 myHyperlink_Click 事件处理程序中将 this.IsHyperlinkChangedCallback 设置为 true 时,我都需要执行 ShowHelp() 方法。

I have tried to replace this line:我试图替换这一行:

IsHyperlinkChangedCallback="{Binding Path=IsHyperlinkChangedCallback, Mode=OneWayToSource}"

By this one:通过这个:

IsHyperlinkChangedCallback="{Binding Path=IsHyperlinkChangedCallback, Mode=OneWayToSource, NotifyOnTargetUpdated=True}"

But it is not working.但它不起作用。

Are you setting the DataContext of myAnotherUserControl.xaml to itself?您是否将 myAnotherUserControl.xaml 的 DataContext 设置为其自身? If so, the following binding probably wouldn't work:如果是这样,以下绑定可能不起作用:

IsHyperlinkChangedCallback="{Binding Path=IsHyperlinkChangedCallback, Mode=OneWayToSource}"

because the binding path points to the myAnotherUserControl.xaml UserControl.因为绑定路径指向 myAnotherUserControl.xaml UserControl。 I would try something like this:我会尝试这样的事情:

IsHyperlinkChangedCallback="{Binding Path=DataContext.IsHyperlinkChangedCallback, Mode=OneWayToSource, RelativeSource={RelativeSource FindAncestor, AncestorType=local:myMainView}}"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 WPF用户控件依赖项属性绑定到ViewModel属性时不起作用 - WPF User Control Dependency Property not working when bound to a ViewModel property 当绑定数据更改时,用户控件上的依赖项属性不会更新属性 - Dependency Property on a user control not updating the property when bound data changes 我可以通过绑定到wpf父控件上的属性的依赖项属性在xaml中设置用户控件datacontext吗? - Can I set my user control datacontext in xaml via a dependency property bound to a property on the parent control in wpf? 从用户控件中xaml的依赖项属性为我的视图模型分配值 - Assigning a value to my view model from my dependency property from xaml in a user control 如何在视图模型中访问绑定到依赖项属性的文本? - How do I access a text bound to a dependency property in the view model? 绑定到另一个VM的用户控件上的依赖项属性 - Dependency Property on a usercontrol that is bound to another VM 绑定依赖属性的WP8.1 / WinRT用户控件绑定 - WP8.1/WinRT User Control Binding from Bound Dependency Property WPF依赖属性中的每个属性都是? - Is every Property in WPF Dependency Property? 依赖属性-从另一个属性继承? - Dependency Property - Inheriting from another property? 未从样式设置依赖项属性 - Dependency Property not set from style
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM