gpt4 book ai didi

wpf - 为什么我不能在我的 UserControl 中重置 TextBox 的背景?

转载 作者:行者123 更新时间:2023-12-05 01:16:40 25 4
gpt4 key购买 nike

我构建了一个 UserControl,它以有趣和有用的方式扩展了 ComboBox 的功能。掉下来的时候是这样的:

My user control

我已经在控件中构建了一大堆功能,它们都可以顺利运行。这让我相信我对自己在做什么有一些线索。您会认为让 UserControl 的样式设置可编辑的 TextBox 的背景画笔是一件小事。事实上,这似乎是不可能的。我很困惑。

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>

此控件中有很多代码隐藏,主要是我用于选择下拉菜单中使用的模板之类的依赖属性。

让我抓狂的是可编辑的文本框。我希望能够从用户控件的样式设置其背景画笔 - 例如,当我在 XAML 中声明这些用户控件之一时,它使用如下样式:
<Style TargetType="{x:Type local:CodeLookupBox}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsRequired}" Value="True">
<Setter Property="EditableTextBoxBackground" Value="{StaticResource RequiredFieldBrush}"/>
</DataTrigger>
</Style.Triggers>
</Style>

我一开始只是简单地设置了 UserControl 的背景,但这设置了可编辑文本框后面的背景。 TextBox 本身仍然是白色的。

在 ComboBox 的模板中,有一个样式可以控制该 TextBox:
<Style x:Key="ComboBoxEditableTextBox" TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>

<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer
x:Name="PART_ContentHost"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

并且有 TextBox(在 ComboBox 的控件模板内)它的坏自我:
<TextBox 
x:Name="PART_EditableTextBox"
Margin="{TemplateBinding Padding}"
Style="{StaticResource ComboBoxEditableTextBox}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}"/>

现在,关于 ComboBoxEditableTextBox 样式的事情有一个明确的元素。那个 ScrollViewer 在里面做什么?我不知道。我可以告诉你,如果我注释掉设置 TextBox 的 ControlTemplate 的样式部分,就会发生非常糟糕的事情。

而且我也知道这一点:如果我明确地将 TextBox 的背景画笔设置为样式的 setter 之一,则不会发生任何事情。如果我在 PART_EditableTextBox 上明确设置背景,则不会发生任何事情。 (我可以设置它的 Foreground 或 FontFamily,它们工作得很好。)

但是,如果我将该 ScrollViewer 的背景显式设置为绿色,瞧,TextBox 会变为绿色。

好的,所以 TextBox 忽略了它自己的背景,并使用它的控件模板中的背景。实际上,严格来说,也不是使用控制模板中的那个。当我设置 ScrollViewer 的背景时,颜色的边缘有一个确定的边距,而不是完全填充 TextBox 的颜色。但是那个边距是白色的,而不是背景色。

除非我能弄清楚为什么 TextBox 忽略了它的背景,否则我必须忍受调整 ScrollViewer。那么如何从用户控件的 EditableTextBoxBackground 属性中获取画笔呢?我已经将此作为一个依赖属性,当它发生更改时会正确引发 PropertyChanged 事件。我在神秘的 ScrollViewer 的 XAML 中绑定(bind)到它,如下所示:
Background="{Binding ElementName=MainControl, 
Path=EditableTextBoxBackground,
Converter={StaticResource DebuggingConverter}}"

我在调试转换器中设置了一个断点。首次绘制控件时,它会被击中两次。第一次,brush的值为null。第二次,这是正确的值。如果我在我的 UserControl 的构造函数中设置该属性,它就可以工作。

所以这就是我所知道的:我的 UserControl 的属性设置正确。 TextBox 样式的绑定(bind)正确绑定(bind)到 UserControl 的属性。 TextBox 的控件模板中 ScrollViewer 上的绑定(bind)绑定(bind)到 right 属性。该属性在更改时使用正确的属性名称引发 PropertyChanged,并且绑定(bind)将值推送到 ScrollViewer 背景属性。

什么也没有发生。

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

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

最佳答案

你有问题。我有答案。

1- 为什么 ScrollViewer 的背景绑定(bind)行为如此奇怪?

当一个 TextBox首先测量,它实例化它的模板。这将创建 ScrollViewer .应用模板后,TextBox检查是否 ScrollViewerBackground属性当前具有空值。如果是这样,它会用 Background.Transparent 覆盖它.这样做会断开您的绑定(bind)。

这就是为什么当你在构造函数中设置它时它会起作用,但稍后不会:TextBox 看到 null 值并用 Background.Transparent 覆盖它,从而破坏了绑定(bind)。

2- ScrollViewer 在那里做什么?
TextBoxControl它实际上并没有处理文本呈现本身的任何血腥细节——如果你浏览可视化树,你会发现这是由另一个 Visual 处理的。名称类似于“TextView”。 TextBox的主要工作实际上是呈现文本框周围的边框和/或让您给它一个全新的外观。
TextBox需要一个带有名为 PART_ContentHost 的元素的模板可以是 ContentPresenterScrollViewer .如果是简单的ContentPresenter ,内部的“TextView”对象被简单地添加到它。如果是 ScrollViewer , TextBox还连接了一些附加功能,例如在聚焦时将文本滚动到 View 中。
ScrollViewer的人生目的是让TextBox中的文字水平滚动,也垂直滚动多行文本框。

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

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

我添加了另外两个相关问题:

4- 为什么设置 TextBox 的 Background 属性不起作用?

没有 WPF 的 Control子类实际上实现了它们的Background属性本身。 Background DependencyProperty 只是一个命名画笔,控件的模板可以根据需要绑定(bind)到它。 TextBox 也是如此。至于任何其他Control .默认 TextBox模板包含一个“chrome”对象,其中包含显示背景的代码,类似于您可能使用边框的内容。由于ComboBox已经显示了自己的“chrome”,它使用自己的TextBox包含 ScrollViewer 的模板但不是周围的 Chrome 。这就是为什么设置 Background TextBox 上的属性(property)在 ComboBox 内没有效果。

5- 如何解决我的问题并在 ComboBox 中绑定(bind) TextBox 的背景颜色

如果你对白边没问题,你可以简单地把 ScrollViewer 换行。在 <Border> 里面并在 <Border> 上设置背景.如果没有,您必须将所需的背景移动到主 ControlTemplate 中提供的 chrome 中。对于ComboBox .

关于wpf - 为什么我不能在我的 UserControl 中重置 TextBox 的背景?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2250606/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com