【问题标题】:Silverlight data binding to parent user control's properties with using MVVM in both controls在两个控件中使用 MVVM 将 Silverlight 数据绑定到父用户控件的属性
【发布时间】:2010-05-17 10:32:16
【问题描述】:

我有两个用户控件(“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));

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

【问题讨论】:

  • UserControlChildView 有 DataContext 吗?
  • Yes.... 请原谅 - UserControl 本身 - 还没有 - 在子控件的构造函数中:this.LayoutRoot.DataContext = this;这是因为很少有内部用户控件应该绑定到用户控件中的某些属性。例如。 Child 用户控件也有这样的属性: public string ButtonText { get { return localDataContext.ButtonText; } 设置 { localDataContext.ButtonText = 值; NotifyPropertyChanged("ButtonText");它用于内部按钮(在子控件内),如下所示:
  • 对非格式化文本感到抱歉 - 无法弄清楚如何修复它:(
  • 查看标签列表下的“编辑”链接,使用它为您的问题添加额外的代码,而不是使用评论。这样,它将以更易读的格式显示。

标签: silverlight binding parent


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 我的错误 - 为简单起见,我决定将 TopMenuButton 重命名为 Child 控件,但忘记在depend.prop.declaration 中重命名 - 抱歉!
    【解决方案3】:

    我很确定您不能在 Silverlight 3 中绑定到用户控件上的依赖项属性。我在 9 个月前自己尝试过,并尝试了各种方法来使其正常工作。最终我在某处读到这根本不可能。我已经在 WPF 中完成了它,所以我想了一会儿,认为这是我的实现。

    所以,从表面上看,您的代码看起来是正确的,但这无济于事。

    我认为它是在 SL4 中修复的。

    您使用的是 SL4 吗?

    【讨论】:

      【解决方案4】:

      嗬嗬!!我已经开始工作了!

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

          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 属性发生更改时触发!

      CheckBoxVisibilitydepend.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;
          }
      

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

      【讨论】:

        【解决方案5】:

        好的,看起来一切正常,我只是被未触发的断点弄糊涂了。

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

        现在我也在父控件中:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-03-24
          • 1970-01-01
          • 2012-07-18
          • 1970-01-01
          • 1970-01-01
          • 2013-08-29
          • 1970-01-01
          相关资源
          最近更新 更多