【问题标题】:How can I set properties of WPF controls with replaced ControlTemplate at runtime?如何在运行时使用替换的 ControlTemplate 设置 WPF 控件的属性?
【发布时间】:2013-02-20 17:50:38
【问题描述】:

我有许多在运行时生成的文本框。我想在执行某个操作时将它们的边框画笔颜色设置为绿色,以及更改边框粗细。就我而言,这必须从代码隐藏中完成。

我的第一个挑战是在鼠标悬停时阻止 TextBox 边框改变颜色。这是通过添加这种样式来实现的:

<UserControl.Resources>
        <Style TargetType="TextBox">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="AllowDrop" Value="true"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TextBoxBase}">
                        <Border 
          Name="Border"
          Padding="1"
          Background="#FFFFFF"
          BorderBrush="#888888"
          BorderThickness="1" >
                            <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
                                <Setter TargetName="Border" Property="BorderBrush" Value="#EEEEEE"/>
                                <Setter Property="Foreground" Value="#888888"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="TreeViewItem">
            <Setter Property="Template" Value="{StaticResource TreeViewWithLines}"/>
            <Setter Property="Padding" Value="0,5,0,5"/>
            <Setter Property="IsExpanded" Value="true"/>
        </Style>
    </UserControl.Resources>
    <ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
        <TreeView Name="tvFilters" Margin="0,10,0,10" Background="White" BorderBrush="White"/>
    </ScrollViewer>
</UserControl>

以上代码适用于我的 UserControl。

接下来,一个新的问题开始出现。每当我尝试在代码隐藏方法中手动更改 BorderBrush 和 BorderThickness 属性时,绝对不会发生任何事情。这是代码:

txt.BorderThickness = new Thickness(3);
txt.BorderBrush = Brushes.Green;

有什么想法吗?

【问题讨论】:

  • 你刚刚问了这个问题,不是吗?我搜索并找到了this
  • 请将标题编辑为真正的问题。
  • WPF Frustrations - WPF 没有挫败感。您正在以 winforms 的方式使用 WPF。这就是你沮丧的原因。
  • I've got a number of TextBoxes which are generated at run-time - 这不是winforms。您需要ItemsControl 或任何派生词。
  • 另外,除非你有充分的理由,否则不要子类化 WPF 控件。

标签: c# .net wpf visual-studio xaml


【解决方案1】:

试试这个作为控制模板:

<ControlTemplate TargetType="{x:Type TextBoxBase}">
     <Border 
      Name="Border"
      Padding="1"
      Background="#FFFFFF"
      BorderBrush="{TemplateBinding BorderBrush}"
      BorderThickness="{TemplateBinding BorderThickness}" >
                        <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter TargetName="Border" Property="Background" Value="#EEEEEE"/>
                            <Setter TargetName="Border" Property="BorderBrush" Value="#EEEEEE"/>
                            <Setter Property="Foreground" Value="#888888"/>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>

您可以通过比较两者来猜测:您正在硬编码为TextBox 可视子树生成的Border 的值。处理这种情况的方法是将视觉对象的属性值绑定到控件的属性值。 TemplateBinding 就是为此而创建的。

另外,请注意,虽然我已经为您提供了答案,但您并没有真正以充分利用其设计的方式使用 WPF。在运行时生成控件最好使用DataTemplate

【讨论】:

  • 感谢您的回复。它几乎有效。现在唯一的问题是默认情况下文本框不显示。它的边框设置为白色吗?
  • 我猜这是你在ControlTemplate 上的触发器。
  • 可能是:Background="#FFFFFF"
  • 它可能得到了默认样式,也与窗口颜色相同,使其看起来不可见。尝试更改背景颜色,而不是仅仅删除它。
  • 实际上将 BorderThickness 更改为 1 有帮助:) 所以问题解决了。感谢您的帮助! +1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-28
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 2011-01-09
  • 1970-01-01
相关资源
最近更新 更多