在两个控件中使用 MVVM 将 Silverlight 数据绑定到父用户控件的属性

发布于 2024-09-02 10:54:40 字数 1841 浏览 2 评论 0原文

我有两个 UserControls(“UserControlParentView”和“UserControlChildView”),两个控件都实现了 MVVM 模式。父控件是子控件的容器,子控件的属性应通过父控件的数据绑定进行更新,以便显示/隐藏子控件内的某些复选框。

父控件描述

UserControlParentViewModel 具有属性:

    private bool isShowCheckbox = false;
    public bool IsShowCheckbox
    {
        get { return isShowCheckbox; }
        set { isShowCheckbox = value; NotifyPropertyChanged("IsShowCheckbox");  }
    }

UserControlParentViewModel - 如何设置父控件的 DataContext:

    public UserControlParentView()
    {
        InitializeComponent();

        this.DataContext = new UserControlParentViewModel();
    }        

UserControlParentView 包含切换按钮(在 XAML 中),绑定到 UserControlParentViewModel 的属性 IsShowCheckbox

<ToggleButton Grid.Column="1" IsChecked="{Binding IsShowCheckbox, Mode=TwoWay}"></ToggleButton>

父控件还包含子元素的实例(在 XAML 中的某处) )

<local:UserControlChildView IsCheckBoxVisible="{Binding IsShowCheckbox}" ></local:UserControlChildView>

因此,当用户切换/取消切换按钮时,应更新子控件中的属性。 子控件包含要从父控件更新的布尔属性,但什么也没发生!断点从未触发!

UserControlChildView 中的属性应从父控件更新(这里我计划使 chechBox 在后面的代码中可见/隐藏):

    public bool IsCheckBoxVisible
    {
        get { return (bool)GetValue(IsCheckBoxVisibleProperty); }
        set { SetValue(IsCheckBoxVisibleProperty, value); }
    }
    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckBoxVisibleProperty =
        DependencyProperty.Register("IsCheckBoxVisible", typeof(bool), typeof(TopMenuButton), new PropertyMetadata(false));

所以问题是 - 我做错了什么?为什么孩子的财产永远不会更新?顺便说一句 - 输出窗口中没有任何绑定错误警告...

I have two UserControls ("UserControlParentView" and "UserControlChildView") with MVVM pattern implemented in both controls. Parent control is a container for Child control and child control's property should be updated by data binding from Parent control in order to show/hide some check box inside Child control.

Parent Control Description

UserControlParentViewModel has property:

    private bool isShowCheckbox = false;
    public bool IsShowCheckbox
    {
        get { return isShowCheckbox; }
        set { isShowCheckbox = value; NotifyPropertyChanged("IsShowCheckbox");  }
    }

UserControlParentViewModel - how I set DataContext of Parent control:

    public UserControlParentView()
    {
        InitializeComponent();

        this.DataContext = new UserControlParentViewModel();
    }        

UserControlParentView contains toggle button (in XAML), bound to UserControlParentViewModel's property IsShowCheckbox

<ToggleButton Grid.Column="1" IsChecked="{Binding IsShowCheckbox, Mode=TwoWay}"></ToggleButton>

Also Parent control contains instance of child element (somewhere in XAML)

<local:UserControlChildView IsCheckBoxVisible="{Binding IsShowCheckbox}" ></local:UserControlChildView>

so property in child control should be updated when user togggle/untoggle button.
Child control contains Boolean property to be updated from parent control, but nothing happened! Breakpoint never fired!

Property in UserControlChildView that should be updated from Parent control (here I plan to make chechBox visible/hidden in code behind):

    public bool IsCheckBoxVisible
    {
        get { return (bool)GetValue(IsCheckBoxVisibleProperty); }
        set { SetValue(IsCheckBoxVisibleProperty, value); }
    }
    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckBoxVisibleProperty =
        DependencyProperty.Register("IsCheckBoxVisible", typeof(bool), typeof(TopMenuButton), new PropertyMetadata(false));

So the question is - what I'm doing wrong? Why child's property is never updated? BTW - there is no any binding error warnings in Output window...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

℉絮湮 2024-09-09 10:54:40

您没有说明断点的放置位置“从未触发!”。我的猜测是您在 IsCheckBoxVisible 属性的 set mutator 方法中放置了一个断点。

您的操作假设是该属性上的绑定将在某个时刻导致在分配值时调用 set 方法。然而,Silverlight 绑定框架实际上直接调用SetValue。它将 IsCheckBoxVisibleProperty 的值和要分配的值传递给 SetValue 方法。

You don't state where you put the breakpoint "never fired!". My guess is you placing a break point in the set mutator method of the IsCheckBoxVisible property.

You are operating under the assumption that the binding on that property will at some point cause the set method to be called when assigning the value. However the Silverlight binding framework actuall calls SetValue directly. It passes to the SetValue method the value of IsCheckBoxVisibleProperty and the value to be assigned.

花想c 2024-09-09 10:54:40

我看不到你的所有代码,所以我无法解决所有问题,但有几个问题:

在你的 DependencyProperty.Register 调用中,你指定了 typeof(TopMenuButton),它应该是 UserControlChildView - 我不知道是否这是否是你的观点?

您没有为更改的属性设置回调方法。为此,您必须在注册 depencencyProperty 之前定义 FrameworkPropertyMetadata 的属性,如下所示:

FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
metadata.PropertyChangedCallback += OnSpacePropertyChanged;

然后您必须声明 OnSpacePropertyChanged,但您至少可以从那里响应设置属性。

I can't see all your code, so I can't work out everything, but a couple of questions:

In your DependencyProperty.Register call, you specify typeof(TopMenuButton), which should be the UserControlChildView - I don't know if that is your view or not?

You don't set up a callback method for property changed. To do this you would have to define the properties for the FrameworkPropertyMetadata, before registering the depencencyProperty like so:

FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
metadata.PropertyChangedCallback += OnSpacePropertyChanged;

You'd then have to declare OnSpacePropertyChanged, but you can at least respond to setting the property from there.

〃安静 2024-09-09 10:54:40

我非常确定您无法在 Silverlight 3 中绑定到用户控件上的依赖属性。9 个月前我亲自尝试过,并尝试了各种方法来使其正常工作。最终我在某处读到这是不可能的。我已经在 WPF 中完成了它,所以我花了一段时间思考它,认为这是我的实现。

因此,从表面上看,您的代码看起来是正确的,但这没有帮助。

我认为SL4 中会修复这个问题。

你用的是SL4吗?

I am pretty sure you can't bind to a dependency property on a user control in Silverlight 3. I've tried it myself 9 months ago, and attempted all sorts of things to get it to work. Eventually I read somewhere that it simply wasn't possible. I have done it in WPF, so was beating my head on it for a while, thinking it was my implementation.

So, on the surface your code looks correct but this won't help.

I thought it was slated as something to be fixed in SL4.

Are you using SL4?

≈。彩虹 2024-09-09 10:54:40

嗬嗬!!我已经让它工作了!

在子控件中,我稍微更改了属性

    public bool IsCheckBoxVisible
    {
        get { return (bool)GetValue(IsCheckBoxVisibleProperty); }
        set { SetValue(IsCheckBoxVisibleProperty, value); }
    }
    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckBoxVisibleProperty =
        DependencyProperty.Register("IsCheckBoxVisible", typeof(bool), typeof(UserControlChildView), new PropertyMetadata(false, new PropertyChangedCallback((d, dc) => 
        {
            var button = d as UserControlChildView;
            button.CheckBoxVisibility = ((bool)dc.NewValue) ? Visibility.Visible : Visibility.Collapsed;
        })));

,所以现在我有新的事件订阅(请参阅匿名方法),并且当父控件中的 IsShowCheckbox 属性更改时,它会触发!

CheckBoxVisibility dependent.property 看起来像这样:

    public Visibility CheckBoxVisibility
    {
        get { return (Visibility)GetValue(CheckBoxVisibilityProperty); }
        set { SetValue(CheckBoxVisibilityProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CheckBoxVisibilityProperty =
        DependencyProperty.Register("CheckBoxVisibility", typeof(Visibility), typeof(UserControlChildView), new PropertyMetadata(Visibility.Collapsed));

serControlChildView 的构造函数看起来像:

    public UserControlChildView()
    {
        InitializeComponent();

        this.LayoutRoot.DataContext = this;
    }

所以看起来它有效!谢谢你们的帮助,伙计们!

Hoho!! I've got it to work!

In child control I've changed property a bit

    public bool IsCheckBoxVisible
    {
        get { return (bool)GetValue(IsCheckBoxVisibleProperty); }
        set { SetValue(IsCheckBoxVisibleProperty, value); }
    }
    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsCheckBoxVisibleProperty =
        DependencyProperty.Register("IsCheckBoxVisible", typeof(bool), typeof(UserControlChildView), new PropertyMetadata(false, new PropertyChangedCallback((d, dc) => 
        {
            var button = d as UserControlChildView;
            button.CheckBoxVisibility = ((bool)dc.NewValue) ? Visibility.Visible : Visibility.Collapsed;
        })));

so now I have new event subscription (see anonymous method) and it fires when in parent control IsShowCheckbox property is changed!

CheckBoxVisibility depend.property looks like this:

    public Visibility CheckBoxVisibility
    {
        get { return (Visibility)GetValue(CheckBoxVisibilityProperty); }
        set { SetValue(CheckBoxVisibilityProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsCheckBoxVisible.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty CheckBoxVisibilityProperty =
        DependencyProperty.Register("CheckBoxVisibility", typeof(Visibility), typeof(UserControlChildView), new PropertyMetadata(Visibility.Collapsed));

Constructor of serControlChildView looks like:

    public UserControlChildView()
    {
        InitializeComponent();

        this.LayoutRoot.DataContext = this;
    }

So seems like it works! Thank you for your help, folks!

゛时过境迁 2024-09-09 10:54:40

好吧,看起来一切都工作正常,我只是对未触发的断点感到困惑。

为简单起见,我决定从子控件中删除 IsCheckBoxVisible boolean dependent.property,并将子控件中的复选框可见性直接绑定到 CheckBoxVisibility dependent.property(类型为 Visibility)。

现在还在父控件中我有这个:

<local:UserControlChildView CheckBoxVisibility="{Binding Path=CheckboxControlVisibility}"></local:UserControlChildView>

所以在父控件中现在我有 CheckboxControlVisibility 属性(类型是 Visibility)

Ok, it seems like everything worked fine and I was confused just by non-fired breakpoint.

For simplicity I've decided to remove IsCheckBoxVisible boolean depend.property from the Child control and to bind checkBox visibility in Child control directly to CheckBoxVisibility depend.property (type is Visibility).

Also in the Parent control now I have this:

<local:UserControlChildView CheckBoxVisibility="{Binding Path=CheckboxControlVisibility}"></local:UserControlChildView>

So in the Parent control now I have CheckboxControlVisibility property (type is Visibility)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文