Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight dependency property snafu,我做错了什么?_Silverlight_Properties - Fatal编程技术网

Silverlight dependency property snafu,我做错了什么?

Silverlight dependency property snafu,我做错了什么?,silverlight,properties,Silverlight,Properties,我正在增强一个开源控件,以添加一些我需要的功能,我陷入了以下问题中,令人绝望: 控件是一个富文本框,支持HTML,但不通过属性;你必须这样做: var sHtml = "..." ctrl.LoadHtml(sHtml) 及 到目前为止还不错。但是我想通过数据绑定设置HTML,所以我创建了一个称为HTML的依赖属性: public static readonly DependencyProperty HtmlProperty = DependencyProperty.R

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

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

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

到目前为止还不错。但是我想通过数据绑定设置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,实现它超出了范围,因为该控件很大,我不想做那么多工作。

为什么需要通知属性系统?您正在尝试更新数据绑定的源吗?控件不必实现INotifyPropertyChanges;该接口必须在为数据绑定提供数据的类上实现

如果现在忽略保存/加载HTML,而只是将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;
    }

计数是一个文本块控件。

为什么需要通知属性系统?您正在尝试更新数据绑定的源吗?控件不必实现INotifyPropertyChanges;该接口必须在为数据绑定提供数据的类上实现

如果现在忽略保存/加载HTML,而只是将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;
    }

计数是一个文本块控件。

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

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

如今,这样的解决方案似乎太过时了,不是吗?我们常常可以说服自己,这样的“低技术”解决方案不可能是正确的,因为它们不“优雅”

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

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

如今,这样的解决方案似乎太过时了,不是吗?我们常常可以说服自己,这样的“低技术”解决方案不可能是正确的,因为它们不“优雅”

“重新进入”导致了什么问题?最初的问题是,在HtmlChangedCallback中,我将html加载到控件中,该控件触发Content_Changed事件,在Content_Changed中调用SetValue导致HtmlChangedCallback触发,在Silverlight逃离无限循环之前,我已经看到了很多次。我试着自己设置一个重新进入的标志,但我发现事件的顺序是不可预测的,有时事件会不按顺序发生,而不是试图去弄清楚,如果我不得不这么做,我可以看出我做错了什么。“重新进入”导致了什么问题?嗯,最初的问题是,在HtmlChangedCallback中,我将html加载到控件中,该控件触发Content_Changed事件,在Content_Changed中调用SetValue导致HtmlChangedCallback触发,在Silverlight逃脱无限循环之前,我已经看到了很多次这样的情况。我试着自己设置一个重新进入标志,但我发现事件的顺序是不可预测的,有时它们会出现顺序错误,而不是试图找出它,如果我不得不这么做,我可以判断我做错了什么。是的,我有一个视图模型,应该在视图中的Html出现时更新(即rich textbox)更改。不,仅存储字符串不起作用,因为属性系统仍然无法知道视图更改了字符串。我的问题是:当发生这种情况时,告诉它的正确方法是什么?是否在{Binding}中指定了双向模式语句?为了使事情正常工作,您需要三件事-模型应该实现INotifyPropertyChanges并调用属性更改事件-视图应该使用dependency属性(使用Get/SetValue存储)-XAML应该指定双向模式我认为这三个步骤还不够,因为我已经完成了所有步骤。进一步考虑后,我认为缺少的部分非常普遍:当您指定从视图更新源的绑定时(例如双向),而视图没有实现INPC,它将如何工作?也就是说,视图必须有一种方法来通知属性已更改,我认为应该可以通过DependencyProperty实现,但我不太确定,因为我找不到。因此,如果我希望视图支持更新源代码,那么视图可能必须实现INPC。View知道更新绑定,因为视图使用SetValue存储属性。SetValue将执行所有必要的更新。我在控件中执行的另一项操作。我总是从通知回调调用rte.Htlm=e.NewValue。当您说这些操作不起作用时,您的意思是什么?您在co上获得modelview集的初始值吗控件?我得到的通知回调很好。但是用户在文本框中键入,现在html已经更改。控件应该如何通知属性系统发生了这种情况?调用SetValue(HtmlProperty,html)不起作用,因为它会触发通知回调。是的,我有一个ViewModel,当视图中的Html(即富文本框)出现时应该更新它更改。不,仅存储字符串不起作用,因为属性系统仍然无法知道视图已更改了字符串。我的问题是:当更改字符串时,正确的方法是什么