在WPF中模拟OwnerDraw控件

时间:2010-07-04 13:41:09

标签: wpf .net-3.5 wpf-controls

过去,我在win表单中开发了一个自定义组合框,它实现了自动完成行为,其中文本的匹配部分以蓝​​色突出显示,而字符串的其余部分具有正常的背景颜色。在win表单中,这可以使用OwerDraw模式相当简单地完成。我需要为WPF控件做类似的事情。我知道WPF模板可用于自定义控件的显示方式,但由于模板本质上是声明性的,我不确定这是如何工作的 - 我需要根据控件的内部状态更改文本的绘制方式。我意识到我会做一些阅读来解决这个问题但是因为WPF是一个很大的话题,所以我会欣赏正确方向的一些指示,所以我知道从哪里开始寻找。

2 个答案:

答案 0 :(得分:0)

在WPF中,控件的外观由模板,样式和有时样式选择器的组合执行。如果你想根据一些数据的状态改变控件的外观(它可能是控件的内部或外部,它并不重要),那么你可以将样式值绑定到这个数据,当它改变时,控件的外观发生变化(前提是有通知机制来传达更改)。您还可以通过称为值转换器(IValueConverter)的类型转换数据值。

作为一个简单的例子,我们可以根据基础数据值更改文本块的文本样式:

// In a C# class
public class MyState : INotifyPropertyChanged
{
     public bool IsEmphasized
     {
         get { return _isEmphasized; }
         set 
         { 
             if (_isEmphasized == value) 
             { 
                 return; 
             } 

             _isEmphasized = value;
             OnPropertyChanged("IsEmphasized"); // This is how to notify that the data is updated
     }
}


// A converter
public class BooleanToBoldConverter : IValueConverter
{
    public Object ConvertTo(Object value)
    {
        if (value is bool)
        {
             if ((bool)value)
             {
                 return FontWeights.Bold;
             }
             else 
             {
                 return FontWeights.Normal;
             }
        }
    }
}

<TextBlock DataContext="{Binding Source={StaticResource myStateInstance}}" 
           FontWeight="{Binding IsEmphasized, Converter={StaticResource BooleanToBoldConverter}}" Text="Text" />

虽然这是一个简单的例子,并且省略了一些细节,但这里要理解的主要思想是我们可以以声明方式从绑定到属性和样式的数据值驱动UI。我们不需要进行实际绘图。

答案 1 :(得分:0)

使用WPF时要记住的重要事项是,在被告知要绘制时不要发出绘图命令,而是通知渲染系统它应该呈现什么类型的形状。如果您想探索低级绘图,请查看DrawingVisual类,它允许您将渲染命令排队到与WinForms画布上的绘图类似的级别。正如codekaizen所提到的,这在WPF中通常不是必需的,但是如果你想要封装在一个控件中,或者你需要实例化大量这些控件并需要更好的性能,那么最好知道你是否有特别棘手的东西。 / p>