【问题标题】:Delayed "rendering" of WPF/Silverlight Dependency Properties?WPF/Silverlight 依赖属性的延迟“渲染”?
【发布时间】:2010-11-30 18:07:01
【问题描述】:

有没有办法知道第一次通过 XAML 绑定访问依赖属性,以便我可以在需要时实际“呈现”属性的值?

我有一个对象(从 Control 派生的类),它有几个 PointCollection 依赖属性,可能包含 100 或 1000 个点。每个属性可能会以不同的方式排列点以用于不同类型的形状(折线、多边形等 - 它比这个更复杂,但你明白了)。通过模板,不同的 XAML 对象使用 TemplateBinding 来访问这些属性。由于我的对象使用模板,我永远不知道我的对象可能正在使用哪些 XAML 形状 - 所以我永远不知道它们可能绑定或不绑定到哪些属性。我只想在实际需要时填写这些 PointCollections。

通常在 .NET 中,我会在属性的 getter 中添加一些逻辑,但这些被 XAML 数据绑定绕过。

我需要一个 WPF 和 Silverlight 兼容的解决方案。

我希望有一个解决方案可以避免我的对象的用户产生任何额外的复杂性。


更新

我发现的一种方法是使用Value Converters。在我的情况下,我有多个积分集合。有一个主要部门。包含数据通常形状的属性。需要两个替代形状以便在其他领域/上下文中重复使用。

起初我有 3 个部门。道具。但是,我可以只拥有一个属性(通常的形状)并使用转换后的值将点转换为我想要的其他 2 个形状。这样做我只在控件中制作一组点。仅在使用时才会产生将点转换为次要形状的费用。现在我的主控件不需要预测数据需要如何查找控件中的每个可能的模板 - 现在是模板设计者的问题。


更新 2

当然,INotifyPropertyChanged 和常规属性是处理此问题的推荐方法。

【问题讨论】:

    标签: wpf silverlight data-binding dependency-properties


    【解决方案1】:

    您不一定必须使用依赖属性来启用数据绑定。但是,如果应将源处的更改传播到绑定的目标,则必须实现 INotifyPropertyChanged。 “正常”的 .NET 属性很容易延迟加载,可能像这样:

    PointCollection points
    
    public PointCollection Points {
      get {
        return this.points ?? (this.points = CreatePoints());
      }
    }
    
    PointCollection CreatePoints() {
      // ...
    }
    

    我不确定如何将INotifyPropertyChanged 放入您的控件中,但是您的控件向系统的其他部分提供数据听起来有点奇怪。也许您需要创建一个包含数据的视图模型,然后您可以让您的控件数据绑定到。

    【讨论】:

    • 我仍在试图弄清楚为什么这个解决方案在我的情况下不起作用。也许这在模板中绑定时不起作用?
    【解决方案2】:

    如果我将您的问题解释为

    当依赖属性发生变化时如何得到通知?

    这是正确的吗?我从您的短语“通常在 .NET 中我会在属性的 getter 中使用一些逻辑,但这些被 XAML 数据绑定绕过”中得出这一点。

    如果我是正确的,那么您可以注册自己的属性更改回调。它总是被调用。谁引起了更改绑定、样式或触发器无关紧要。以下代码 sn-p 摘自 MSDN 文章“Dependency Property Callbacks and Validation”:

    public static readonly DependencyProperty CurrentReadingProperty = 
    
        DependencyProperty.Register(
            "CurrentReading",
            typeof(double),
            typeof(Gauge),
            new FrameworkPropertyMetadata(
                Double.NaN,
                FrameworkPropertyMetadataOptions.AffectsMeasure,
                new PropertyChangedCallback(OnCurrentReadingChanged),
                new CoerceValueCallback(CoerceCurrentReading)
            ),
            new ValidateValueCallback(IsValidReading)
        );
        public double CurrentReading
        {
          get { return (double)GetValue(CurrentReadingProperty); }
          set { SetValue(CurrentReadingProperty, value); }
        }
    

    您的收获是 OnCurrentReadingChanged() 方法。希望这会有所帮助:)。

    【讨论】:

    • 我很确定问题是关于如何在对象中第一次访问依赖属性的值时“延迟加载”它,而不是如何在依赖属性更改时得到通知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-30
    • 2023-03-16
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    相关资源
    最近更新 更多