Silverlight依赖属性snafu,我做错了什么?

时间:2010-08-09 22:31:23

标签: silverlight properties

我正在增强一个开源控件来添加一些我需要的功能,而且我在以下问题中陷入了绝望的困境:

该控件是一个富文本框,支持HTML但不支持属性;你必须做这样的事情:

var sHtml = "..."
ctrl.LoadHtml(sHtml)

var sHtml = ctrl.SaveHtml()

到目前为止一切顺利。但我想通过数据绑定设置HTML,所以我创建了一个名为Html的依赖属性:

    public static readonly DependencyProperty HtmlProperty =
        DependencyProperty.Register(
            "Html",
            typeof(string),
            typeof(RichTextEditor),
            new PropertyMetadata(string.Empty, new PropertyChangedCallback(HtmlChangedCallback))
            );

    public string Html
    {
        get {return (string)GetValue(HtmlProperty);}

        set {SetValue(HtmlProperty, value);}
    }

    private static void HtmlChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        //get the control
        var rte = (RichTextEditor)d;

        //got here, so load the html
        rte.TextBox.LoadHtml((string)e.NewValue);
    }

一切正常。我遇到的问题是,当控件的内容发生变化时,我无法弄清楚如何通知属性系统。该控件有一个ContentChanged事件,所以我尝试了这个:

    private void rtb_ContentChanged(object sender, RichTextBoxEventArgs e)
    {
        //tell the html prop that it changed
        SetValue(HtmlProperty, rtb.SaveHtml());
    }

但是这会触发HtmlChangedCallback并重新进入会导致问题。所以我尝试使用重新入口标志,但是因为事件的顺序比我想象的要复杂得多,所以我觉得我必须遗漏一些东西,所以我在这里问。请帮忙!提前谢谢。

顺便说一句,控件不支持INotifyPropertyChanged,并且实现它超出范围,因为控件很大,我不想做那么多工作。

2 个答案:

答案 0 :(得分:0)

为什么需要通知物业系统?您是否尝试更新数据绑定的来源?控件不必实现INotifyPropertyChanges;此接口必须在提供数据绑定数据的类上实现。

如果您暂时忽略Save / LoadHtml并将HTML存储为字符串,该怎么办?它没有问题吗?

这是一个适合我的例子

class MyControl
{
    public int Value
    {
        get
        {
            return (int)GetValue(ValueProperty);
        }

        set
        {
            SetValue(ValueProperty, value);
            Count.Text = value.ToString();
        }
    }

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value",
            typeof(int),
            typeof(Vote),
            new PropertyMetadata(0, OnValueChanged));

    private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        ((MyControl)d).Value = (int)e.NewValue;
    }

Count是一个文本块控件。

答案 1 :(得分:0)

这是一个经典的小问题,通常用一个简单的布尔标志来解决。

private bool suppressHtmlChanged = false;

private static void HtmlChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{

    var rte = (RichTextEditor)d;

    if (!rte.suppressHtmlChanged)
        rte.TextBox.LoadHtml((string)e.NewValue);
}


private void rtb_ContentChanged(object sender, RichTextBoxEventArgs e)
{
    suppressHtmlChanged = true;
    SetValue(HtmlProperty, rtb.SaveHtml());
    suppressHtmlChanged = false;
}

现在,这些解决方案看起来过时了,不是吗,我们常常可以说服自己这样一种“低技术”的解决方案是不对的,因为它们并不“优雅”。