我正在增强一个开源控件来添加一些我需要的功能,而且我在以下问题中陷入了绝望的困境:
该控件是一个富文本框,支持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,并且实现它超出范围,因为控件很大,我不想做那么多工作。答案 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;
}
现在,这些解决方案看起来过时了,不是吗,我们常常可以说服自己这样一种“低技术”的解决方案是不对的,因为它们并不“优雅”。