【问题标题】:WPF binding does not work with a UserControlWPF 绑定不适用于 UserControl
【发布时间】:2013-05-19 16:24:20
【问题描述】:

在我的MainViewModel 中,我有一个由用户设置的属性。当收到新值时,我想在我的UserControl 更新信息。问题是绑定不起作用。我希望它的工作方式如下。更改SelectedDay后,后面的用户控件代码中的Day属性也发生了变化,从而调用了CalculateDay方法。但是,这个方法永远不会被调用!

我想,原因很简单,我只是不完全了解绑定机制,但我无法弄清楚哪里出了问题,现在我真的需要一些帮助。我已经检查了许多类似的问题,但从未找到合适的答案。

我的代码:

MainViewModel

private Day _selectedDay;
public Day SelectedDay
{
    get { return _selectedDay; }
    set
    {
        _selectedDay = value;
        RaisePropertyChanged("SelectedDay");
    }
}

主窗口 XAML

<controls:DayControl Day="{Binding SelectedDay, Mode=TwoWay}"></controls:DayControl>

UserCotrol 背后的代码

public Day Day
{
    get { return (Day)GetValue(DayProperty); }
    set
    {
        SetValue(DayProperty, value);
        CalculateDay();
    }
}

public static readonly DependencyProperty DayProperty =
    DependencyProperty.Register("Day", typeof(Day), typeof(DayControl), new PropertyMetadata(new Day()));

【问题讨论】:

    标签: wpf mvvm binding user-controls dependency-properties


    【解决方案1】:

    据此msdn

    除特殊情况外,您的包装器实现 应该分别只执行 GetValue 和 SetValue 操作。 其原因在主题 XAML 加载和 依赖属性。

    您应该在依赖属性的定义中使用 PropertyChangedCallBack。以下是直接取自msdn的代码。

    public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register(
      "AquariumGraphic",
      typeof(Uri),
      typeof(AquariumObject),
      new FrameworkPropertyMetadata(null,
          FrameworkPropertyMetadataOptions.AffectsRender, 
          new PropertyChangedCallback(OnUriChanged)
      )
    );
    

    定义您的 CalculateDay 代替上面的 OnUriChanged

    【讨论】:

    • 感谢您的提示,这是一个非常好的提示。但是,它并没有解决我的问题。 SetValue() 也没有被调用,Day 属性也没有更新。
    • 由于 WPF 完全绕过包装器,因此您不应将任何其他逻辑放入自定义依赖项属性的包装器的集合定义中。如果您将此类逻辑放在集合定义中,那么当在 XAML 中而不是在代码中设置属性时,将不会执行该逻辑。您不能保证调用 Wrappers Get/Set。所以从你的 Wrappers 中删除所有逻辑并放入 PropertyChangedCallback。 Day 属性包装器是 Dependency 属性定义的一部分,而不是您的 ViewModel。当您在代码中读取 Day 属性时,可能不会调用 Get。设置相同
    【解决方案2】:

    我看不出您在后面的代码中使用 DependencyProperty 的原因。您在MainViewModel 中拥有您所需要的一切。

    在后面的代码中添加到构造函数:

    this.DataContext = new MainViewModel(); 
    

    接下来,将CalculateDay方法移动到MainViewModel,并在SelectedDay的set方法中调用它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      相关资源
      最近更新 更多