Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.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 为什么可以';我不能在UserControl中重置文本框的背景吗?_Wpf_Templates_User Controls_Controls_Styles - Fatal编程技术网

Wpf 为什么可以';我不能在UserControl中重置文本框的背景吗?

Wpf 为什么可以';我不能在UserControl中重置文本框的背景吗?,wpf,templates,user-controls,controls,styles,Wpf,Templates,User Controls,Controls,Styles,我构建了一个UserControl,它以有趣而有用的方式扩展了ComboBox的功能。当它被放下时,看起来是这样的: 我已经在控件中构建了一整套功能,它们都工作得很顺利。这让我相信我对自己正在做的事情有些线索。您可能认为让UserControl的样式设置可编辑文本框的背景笔刷是一件小事。事实上,这似乎是不可能的。我很困惑 UserControl的XAML非常简略(您会为此感谢我),如下所示: <UserControl x:Class="MyApp.CodeLookupBox" x:Nam

我构建了一个UserControl,它以有趣而有用的方式扩展了ComboBox的功能。当它被放下时,看起来是这样的:


我已经在控件中构建了一整套功能,它们都工作得很顺利。这让我相信我对自己正在做的事情有些线索。您可能认为让UserControl的样式设置可编辑文本框的背景笔刷是一件小事。事实上,这似乎是不可能的。我很困惑

UserControl的XAML非常简略(您会为此感谢我),如下所示:

<UserControl x:Class="MyApp.CodeLookupBox" x:Name="MainControl">
    <UserControl.Resources>
       <!-- tons of DataTemplates and Styles, most notably the style that
            contains the control template for the ComboBox -->
    <UserControl.Resources>
    <ComboBox x:Name="ComboBox" 
                   Margin="0" 
                   Style="{DynamicResource ComboBoxStyle1}" 
                   VerticalAlignment="Top"
                   ItemTemplate="{StaticResource GridViewStyleTemplate}"/>
</UserControl>
<Style TargetType="{x:Type local:CodeLookupBox}">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsRequired}" Value="True">
            <Setter Property="EditableTextBoxBackground" Value="{StaticResource RequiredFieldBrush}"/>
        </DataTrigger>
    </Style.Triggers>
</Style>
Background="{Binding ElementName=MainControl, 
    Path=EditableTextBoxBackground, 
    Converter={StaticResource DebuggingConverter}}"
我在调试转换器中设置了断点。第一次绘制控件时,它会被命中两次。第一次,笔刷的值为null。第二次,它是正确的值。如果我在UserControl的构造函数中设置了属性,它就会工作

我知道的是:我的UserControl属性设置正确。TextBox样式上的绑定已正确绑定到UserControl的属性。TextBox控件模板中ScrollViewer上的绑定绑定到right属性。当属性发生更改时,该属性将使用正确的属性名称引发PropertyChanged,绑定将该值推出到ScrollViewer背景属性

什么也没发生

所以我想我有一个三部分的问题:1)为什么?2) 那个ScrollViewer到底在那里干什么?我有我的怀疑,但这是一个早上,我越来越难以表达它们。3) 为什么Blend给了我一个不同的控件模板,而不是一个更容易理解的模板


真的,任何帮助都将不胜感激。

您有问题。我有答案

1-为什么ScrollViewer的后台绑定行为如此奇怪?

当第一次测量
文本框时,它将实例化其模板。这将创建
ScrollViewer
。应用模板后,
文本框
将检查
ScrollViewer
Background
属性当前是否具有空值。如果是这样,它将用
背景.Transparent
覆盖它。这样做会断开绑定

这就是为什么在构造函数中设置它时它会起作用,但以后不会起作用:文本框看到空值并用Background.Transparent重写它,从而破坏绑定

2-ScrollViewer在那里做什么?

TextBox
是一个
控件
,它实际上不处理文本显示本身的任何血淋淋的细节-如果你浏览可视化树,你会看到这是由另一个名为“TextView”的
visual
处理的
TextBox
的主要工作实际上是显示文本框周围的边框和/或允许您给它一个全新的外观

TextBox
需要具有名为
PART\u ContentHost
的元素的模板,该元素可以是
ContentPresenter
ScrollViewer
。如果它是一个简单的
ContentPresenter
,则只需将内部“TextView”对象添加到它。如果它是一个
ScrollViewer
TextBox
还连接了一些附加功能,例如在聚焦时将文本滚动到视图中

ScrollViewer
在生活中的用途是允许
TextBox
中的文本水平滚动,也允许多行文本框垂直滚动

3-为什么Blend给了我一个不同的控制模板

Blend从引用的程序集加载实际的
ControlTemplate
XAML,在本例中为当前系统主题加载PresentationFramework.dll和关联的主题dll。因此,它将加载您安装的NetFramework版本中实际使用的内容。您链接的站点上的XAML只是示例代码,而不是实际的NET Framework XAML

我又添加了两个相关问题:

4-为什么设置文本框的后台属性不起作用?

WPF的
控件
子类中没有一个真正实现其
后台
属性本身。
Background
dependencProperty只是一个命名笔刷,控件的模板可以根据需要绑定到它。对于
文本框
和任何其他
控件
都是如此。默认的
TextBox
模板包含一个“chrome”对象,该对象包含用于显示背景的代码,类似于您可能使用边框的代码。由于
ComboBox
已经显示了自己的“chrome”,因此它使用自己的
TextBox
模板,其中包括
ScrollViewer
,但不包括周围的chrome。这就是为什么在
组合框
中的
文本框
上设置
背景
属性无效的原因

5-如何解决问题并将文本框的背景色绑定到组合框中


如果您对白色边距满意,只需将
滚动查看器
包装在
中,然后在
上设置背景即可。如果没有,你必须将所需的背景移动到
组合框的主
控件模板
中提供的chrome中。“你会认为让用户控件的样式设置可编辑文本框的背景笔刷是一件小事。事实上,这似乎是不可能的。”-哈哈,说得好。我现在也遇到了同样的事情。有没有一本书详细描述了这样的事情,还是基于经验+反射器?
<TextBox 
    x:Name="PART_EditableTextBox" 
    Margin="{TemplateBinding Padding}" 
    Style="{StaticResource ComboBoxEditableTextBox}" 
    HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
    IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"/>
Background="{Binding ElementName=MainControl, 
    Path=EditableTextBoxBackground, 
    Converter={StaticResource DebuggingConverter}}"