【问题标题】:DependencyProperty not updatedDependencyProperty 未更新
【发布时间】:2012-08-08 08:40:25
【问题描述】:

我有一个简单的 WPF 窗口,其中有一个 TabItem,其中包含一个带有颜色的 ComboBox 和一个使用该颜色绘制矩形的自定义 Canvas。在我的 PaintCanvas 中,我有一个这样的 DependencyProperty:

class PaintCanvas : System.Windows.Controls.Canvas
{
    public static readonly DependencyProperty PaintObjectProperty = DependencyProperty.Register(
      "PaintObject", typeof(PaintObject), typeof(PaintCanvas), new PropertyMetadata(OnPaintObjectChanged));


    public PaintObject PaintObject
    {
        get { return this.GetValue(PaintObjectProperty) as PaintObject; }
        set 
        {
            this.SetValue(PaintObjectProperty, value);
        }
    }

    private static void OnPaintObjectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        PaintCanvas canvas = (PaintCanvas)d;

        // Update stuff

        canvas.InvalidateVisual();
    }

    protected override void OnRender(DrawingContext dc)
    {
        base.OnRender(dc);

        if (PaintObject != null)
        {
            dc.DrawRectangle(new SolidColorBrush(PaintObject.Color), null, new Rect(0, 0, PaintObject.Width, PaintObject.Height));
        }
    }
}

PaintObject 依赖属性在 xaml 中绑定到其在 PaintViewModel 中的对应属性:

<TabControl>
    <TabItem DataContext="{Binding PaintViewModel}">
        <StackPanel >
            <ComboBox ItemsSource="{Binding Colors}" SelectedItem="{Binding Color}" />
            <my:PaintCanvas Width="100" Height="100" PaintObject="{Binding PaintObject}" />
        </StackPanel>
    </TabItem>
</TabControl>

PaintViewModel 是 Window 的 ViewModel 中的一个属性:

class MainViewModel
{
    PaintViewModel paintViewModel;

    public MainViewModel()
    {
        paintViewModel = new PaintViewModel();
    }

    public PaintViewModel PaintViewModel
    {
        get { return paintViewModel; }
    }

    ...
}

实际的 PaintViewModel:

class PaintViewModel : INotifyPropertyChanged
{
    PaintObject paintObject;
    ObservableCollection<Color> colors = new ObservableCollection<Color>();
    Color currentColor;

    public PaintObject PaintObject
    {
        get { return paintObject; }
        set { paintObject = value; RaisePropertyChanged("PaintObject"); }
    }

    public ObservableCollection<Color> Colors
    {
        get { return colors; }
    }

    public Color Color
    {
        get { return currentColor; }
        set { 
            currentColor = value; 
            RaisePropertyChanged("Color");
            paintObject.Color = currentColor;
            RaisePropertyChanged("PaintObject");
        }
    }

    // Constructors and INotifyPropertyChanged stuff... 
}

TabItem 似乎已正确绑定到视图模型,因为颜色组合框可以正常工作。但是,尽管绘制对象已更新并调用了 RaisePropertyChanged("PaintObject"),但 PaintCanvas 中的 DependencyProperty 永远不会更新。我在这里做错了什么??

【问题讨论】:

  • 你怎么知道“PaintCanvas 中的 DependencyProperty 永远不会更新”?你是在OnPaintObjectChanged 中设置断点还是仅仅因为颜色没有改变?
  • @Clemens:是的,两者都有。 :-)
  • (OnPaintObjectChanged 方法被调用了吗?,对不起,同步 cmets)
  • 不,永远不会调用 OnPaintObjectChanged,这让我很困惑。

标签: c# wpf xaml data-binding dependency-properties


【解决方案1】:

我没有看到您更改了对 PaintObject 的引用,您更改了它的一个属性(颜色)并在 PaintObject 更改时触发,因为它不是,所以依赖属性不会刷新

作为一种解决方案,您可以在 PaintCanvas 中添加 Color 依赖属性,并将 Color 绑定到 xaml 中的 PaintObject.Color

<my:PaintCanvas Width="100" Height="100" PaintObject="{Binding PaintObject}" Color={Binding PaintObject.Color} />

如果你不忘记在 PaintObject 中调用 Color 属性的 NotifyPropertyChanged,PaintConvas Color 属性将被触发进行更改

我发现你的设计有些混乱,尽量保持简单

【讨论】:

  • 对,除非 PaintObject 的属性也是依赖属性或引发 PropertyChanged 事件,否则这将不起作用。
  • 谢谢,就是这样!创建一个新的绘画对象而不是仅仅更改颜色可以正常工作,我想您关于绑定该特定属性的建议也可以。假设 PaintObject 是一个复杂得多的对象,它的许多属性可能会发生变化,您对如何进行此绑定有什么建议吗?
  • 另外,您所指的设计中的混乱是什么?我应该提到两个不同视图模型的原因是实际上有许多看起来相同的 TabItems。在我的实际应用中,我有一个CustomControl,就是这样绑定PaintViewModel的,而PaintObject也比较复杂。但如果事情可以做得更好,我不介意重构。
  • 好吧,你有几个选择,你可以在 PaintObject 中创建一个事件,并订阅依赖属性的变化,你可以通过代码绑定到所有属性,使用 BindingOperations,你可以克隆 PoinObject 就像你已经做了...
  • @ekholm,如果不考虑漏洞逻辑,很难做出建议。我不喜欢视图模型保留颜色,因为它是视图的东西,不清楚是 PaintObject ViewModel 还是 Model 等等,但这一切都取决于你的业务逻辑,所以我可能错了
猜你喜欢
  • 2021-06-23
  • 2015-03-03
  • 2011-12-01
  • 1970-01-01
  • 2013-03-13
  • 2011-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多