Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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
在WPF中模拟OwnerDraw控件_Wpf_.net 3.5_Wpf Controls - Fatal编程技术网

在WPF中模拟OwnerDraw控件

在WPF中模拟OwnerDraw控件,wpf,.net-3.5,wpf-controls,Wpf,.net 3.5,Wpf Controls,在过去,我在win forms中开发了一个自定义组合框,它实现了自动完成行为,其中文本的匹配部分以蓝色突出显示,而字符串的其余部分具有正常的背景色。在win表单中,使用OwerDraw模式可以相当简单地完成此操作。我需要为WPF控件做类似的事情。我知道在WPF中,模板可用于自定义控件的显示方式,但由于模板本质上是声明性的,我不确定这将如何工作-我需要根据控件的内部状态更改文本的绘制方式。我意识到我需要做一些阅读来弄清楚这一点,但由于WPF是一个大主题,我希望有一些指向正确方向的指针,这样我就知道

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

在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" />
//在C#类中
公共类MyState:INotifyPropertyChanged
{
公共场所被强调
{
获取{return}
设置
{ 
如果(_isemphasised==值)
{ 
回来
} 
_i强调=价值;
OnPropertyChanged(“IsEmphasised”);//这是通知数据已更新的方式
}
}
//转换器
公共类BooleanToBoldConverter:IValueConverter
{
公共对象转换为(对象值)
{
if(值为bool)
{
如果((布尔)值)
{
返回字体:粗体;
}
其他的
{
返回正常值;
}
}
}
}

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

使用WPF需要记住的重要一点是,在被告知进行绘图时,您不会发出绘图命令,而是告诉渲染系统它应该渲染什么类型的形状。如果你想探索低级绘图,看看这个类,它允许你在类似于WinForms画布上绘图的级别上排队渲染命令。正如codekaizen提到的,这在WPF中通常是不必要的,但最好知道你是否有一些如果您希望封装在控件中,或者需要实例化大量此类控件并需要更好的性能,则这一点尤其棘手。

在本例中,您将现有控件属性绑定到某个数据。在自动完成组合框的示例中,我需要更改文本框的绘图行为组合的(但不是下拉列表中的项目)。没有一个现有的小部件具有正确的属性,所以我需要创建一个吗?可能类似于一个名为HighlightUpToThisIndex的带有和整数属性的TextBlock?(下面继续)。此外,我需要创建一个新的可重用的自包含组合框-在win窗体中,您可以为现有的自定义创建一个继承控件。这在WPF中是如何工作的?也许我想做的只是您所描述的更复杂的版本,但我还没有被说服。我想我对WPF的了解还不够。是吗目前正在阅读发布的WPF控件开发-也许这会有所帮助。我看了一下使用reflector的ComboBox的代码。与UI相关的代码很少。大多数代码都与行为相关,正如codekaizen提到的,行为和外观之间有很强的分离。不过,我认为定制exitin的行为g控件可能具有挑战性,因为控件可能并不总是提供您需要的详细级别的公共挂钩。