WPF:在 XAML 中禁用控件时无法设置自定义控件的背景颜色

发布于 2024-11-02 12:01:30 字数 5008 浏览 0 评论 0原文

我在继承的 WPF/C# 项目中有一个自定义 IPAddressBox 控件。该控件工作得很好,但它不允许我在禁用该控件时更改 XAML 中的背景(我可以通过后面的代码成功更改它,但我拼命地尝试打破 UI 和业务逻辑之间的耦合并希望为了摆脱“了解我的业务代码中的每个 UI 细节”,

我有几个基于组合框的选择来启用/禁用的控件 - 该组合是一个备份位置 - 有 2 个选择 - DVD-RW 或网络。他们选择网络,我有一个 IP 地址我可以通过绑定类中的 IsEnabled 属性成功启用/禁用控件,但我似乎无法使 IP 控件的背景变成灰色我拥有所有代码。对于控件(XAML 和 CS)以及我自己的代码 - 我对 WPF 相当陌生,并且正在尝试学习正确地做事,而不是立即将所有事件路由到 CS 并在那里执行......

这里是我的 XAML 的一部分(最新)尝试更改背景:

<automation:IPAddressBox  Grid.Column=" 4" Grid.Row="4"                 
 Name="ipAddressBox_BackupIpAddress" Background="White" 
 IsEnabled="{Binding Path=IsBackupEnabled}">

 <automation:IPAddressBox.Style>
      <Style TargetType="{x:Type automation:IPAddressBox}">
      <Style.Triggers>
          <DataTrigger Binding="{Binding Path=IsBackkupEnabled}" Value="false">
        <Setter Property="Background" Value="LightGray"/>
         </DataTrigger>
     </Style.Triggers>
     </Style>
  </automation:IPAddressBox.Style>
</automation:IPAddressBox> "

<-- Other related controls -->

<Label Grid.Column="6" Grid.Row="2" Name="label_BackupUserID" Content="User ID:" 
       HorizontalAlignment="Right" IsEnabled="{Binding Path=IsBackupEnabled}" />

<TextBox Grid.Column="8" Grid.Row="2" Name="txtBackupUserID" 
     IsEnabled="{Binding Path=IsBackupEnabled}" />

<Label Grid.Column="6" Grid.Row="4" Name="label_BackupPassword" Content="Password:" 
       HorizontalAlignment="Right" IsEnabled="{Binding Path=IsBackupEnabled}" />

<PasswordBox Grid.Column="8" Grid.Row="4" Name="passwordBox_BackupPassword" 
       IsEnabled="{Binding Path=IsBackupEnabled}" />

请注意,我将背景颜色设置为白色,因为基础控件由于某种原因是“透明的”。我已经在控件和我自己的代码中尝试了各种样式/触发器,但都无法完成我需要的操作 - 即将背景变成灰色

- 这是供参考的控件 XAML - 我不确定如果我需要包含控件上可用的公共属性,那么基本上还有 2 个感兴趣的内容 - Foreground(类型画笔)和 BorderBrush(也类型画笔) - 我尝试将 IsEnabled 添加到控件上的属性,尝试更改背景那里——又没有运气 - 它唯一起作用的地方是在我的代码中组合框的“OnSelectionChanged”中。

这是 IpAddressBox 的简化 xaml(我删除了一些显示无效值的弹出窗口)

<UserControl.Resources>
  <Style x:Key="textBoxStyle" TargetType="{x:Type TextBoxBase}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
       <Setter Property="Template">
       <Setter.Value>
           <ControlTemplate TargetType="{x:Type TextBoxBase}">
          <ScrollViewer x:Name="PART_ContentHost" Margin="0,3,0,0" />
           </ControlTemplate>
       </Setter.Value>
       </Setter/>
   </Style>
</UserControl.Resources>

<Border Name="border_IpAddressBox" BorderBrush="Black" BorderThickness="1">
   <Grid>
      <automation:NumericTextBox Height="23" x:Name="numericTextBox1" Width="30" 
      MinWidth="30" MaxWidth="30" HorizontalAlignment="Left" VerticalAlignment="Top"
      BorderBrush="Transparent" MaxLength="3" HorizontalContentAlignment="Center"
      ContextMenu="{StaticResource contextMenu_TextBox}" Background="Transparent" 
      Style="{StaticResource textBoxStyle}" />

     <automation:NumericTextBox Height="23" Margin="42,0,0,0" x:Name="numericTextBox2" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30" 
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" 
       Style="{StaticResource textBoxStyle}" IsTabStop="False" />

     <automation:NumericTextBox Height="23" Margin="84,0,0,0" x:Name="numericTextBox3" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30" 
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" Style="{StaticResource 
       textBoxStyle}" IsTabStop="False" />

     <automation:NumericTextBox Height="23" Margin="126,0,0,0" x:Name="numericTextBox4" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30"  
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" Style="{StaticResource 
       textBoxStyle}" IsTabStop="False" />

    <Label Name="label1" Height="23" Margin="30,0,0,0" VerticalAlignment="Top" 
       HorizontalAlignment="Left" Width="12">.</Label>

    <Label Name="label2" Height="23" HorizontalAlignment="Left" Margin="72,0,0,0" 
       VerticalAlignment="Top" Width="12">.</Label>

    <Label Name="label3" Height="23" HorizontalAlignment="Left" Margin="114,0,0,0" 
       VerticalAlignment="Top" Width="12">.</Label>

    </Grid>
  </Border>
</UserControl>

NumericTextBox 只是另一个限制文本的用户控件输入数值 - 仅 CS 实现,不涉及 XAML

- 20 年的软件开发经验,这是我发布的第一个问题 - Google 通常会这样做,但这次不是:)

——布莱恩

I have a custom IPAddressBox control in a WPF/C# project I inherited. The control works great, but it doesn't allow me to change the background within XAML when the control is disabled (I can successfully change it via code behind, but I am trying desperately to break the coupling between the UI and business logic and want to get away from "Knowing every UI detail in my business code"

I have several controls that are enabled/disabled based on the selection of a combo box - the combo is a backup location - with 2 choices - DVD-RW or Network. If they select Network, I have an IPAddress control and text/password controls for the credentials. I can successfully enable/disable the controls by binding the IsEnabled property in the class, but I can't seem to get the background of the IP control to turn grey. I have all the code for the control (XAML & CS) as well as my own code - I'm fairly new to WPF and am attempting to learn to do things right rather than immediately routing all events to the CS and doing it there....

Here is part of my XAML with my (latest) attempt to change the background:

<automation:IPAddressBox  Grid.Column=" 4" Grid.Row="4"                 
 Name="ipAddressBox_BackupIpAddress" Background="White" 
 IsEnabled="{Binding Path=IsBackupEnabled}">

 <automation:IPAddressBox.Style>
      <Style TargetType="{x:Type automation:IPAddressBox}">
      <Style.Triggers>
          <DataTrigger Binding="{Binding Path=IsBackkupEnabled}" Value="false">
        <Setter Property="Background" Value="LightGray"/>
         </DataTrigger>
     </Style.Triggers>
     </Style>
  </automation:IPAddressBox.Style>
</automation:IPAddressBox> "

<-- Other related controls -->

<Label Grid.Column="6" Grid.Row="2" Name="label_BackupUserID" Content="User ID:" 
       HorizontalAlignment="Right" IsEnabled="{Binding Path=IsBackupEnabled}" />

<TextBox Grid.Column="8" Grid.Row="2" Name="txtBackupUserID" 
     IsEnabled="{Binding Path=IsBackupEnabled}" />

<Label Grid.Column="6" Grid.Row="4" Name="label_BackupPassword" Content="Password:" 
       HorizontalAlignment="Right" IsEnabled="{Binding Path=IsBackupEnabled}" />

<PasswordBox Grid.Column="8" Grid.Row="4" Name="passwordBox_BackupPassword" 
       IsEnabled="{Binding Path=IsBackupEnabled}" />

Note that I am setting the background color to White as the base control is "transparent" for some reason. I've tried various styles/triggers on both the contol and within my own code, all will no luck in doing what I need - which is to turn the background grey

-- Here is the control XAML for reference - I'm not sure if I need to include the public properties available on the control also there is basically 2 of interest - Foreground (type brush) and BorderBrush (also type brush) - I have tried adding IsEnabled to the properties on the control, trying to change the background there - again with no luck - the only place where it does work is in the "OnSelectionChanged for the combobox in my code.

Here is the simplified xaml for the IpAddressBox (I removed a few Popups that display for invalid values)

<UserControl.Resources>
  <Style x:Key="textBoxStyle" TargetType="{x:Type TextBoxBase}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
       <Setter Property="Template">
       <Setter.Value>
           <ControlTemplate TargetType="{x:Type TextBoxBase}">
          <ScrollViewer x:Name="PART_ContentHost" Margin="0,3,0,0" />
           </ControlTemplate>
       </Setter.Value>
       </Setter/>
   </Style>
</UserControl.Resources>

<Border Name="border_IpAddressBox" BorderBrush="Black" BorderThickness="1">
   <Grid>
      <automation:NumericTextBox Height="23" x:Name="numericTextBox1" Width="30" 
      MinWidth="30" MaxWidth="30" HorizontalAlignment="Left" VerticalAlignment="Top"
      BorderBrush="Transparent" MaxLength="3" HorizontalContentAlignment="Center"
      ContextMenu="{StaticResource contextMenu_TextBox}" Background="Transparent" 
      Style="{StaticResource textBoxStyle}" />

     <automation:NumericTextBox Height="23" Margin="42,0,0,0" x:Name="numericTextBox2" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30" 
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" 
       Style="{StaticResource textBoxStyle}" IsTabStop="False" />

     <automation:NumericTextBox Height="23" Margin="84,0,0,0" x:Name="numericTextBox3" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30" 
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" Style="{StaticResource 
       textBoxStyle}" IsTabStop="False" />

     <automation:NumericTextBox Height="23" Margin="126,0,0,0" x:Name="numericTextBox4" 
       VerticalAlignment="Top" HorizontalAlignment="Left" Width="30" MinWidth="30"  
       MaxWidth="30" BorderBrush="Transparent" MaxLength="3" 
       HorizontalContentAlignment="Center" ContextMenu="{StaticResource 
       contextMenu_TextBox}" Background="Transparent" Style="{StaticResource 
       textBoxStyle}" IsTabStop="False" />

    <Label Name="label1" Height="23" Margin="30,0,0,0" VerticalAlignment="Top" 
       HorizontalAlignment="Left" Width="12">.</Label>

    <Label Name="label2" Height="23" HorizontalAlignment="Left" Margin="72,0,0,0" 
       VerticalAlignment="Top" Width="12">.</Label>

    <Label Name="label3" Height="23" HorizontalAlignment="Left" Margin="114,0,0,0" 
       VerticalAlignment="Top" Width="12">.</Label>

    </Grid>
  </Border>
</UserControl>

NumericTextBox is simply another user control that limits text input to numeric values - Only CS implementation, no XAML involved.

Thanks in advance for any help - 20 years in software development and this is my first question I've ever posted - Google usually does the trick, but not this time :)

-- Brian

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瘫痪情歌 2024-11-09 12:01:31

您无法将背景显式设置为白色,然后使用应用样式的值覆盖它。样式值比所谓的本地值“弱”,并且永远不会覆盖它。只需将您的白色背景设置也移入样式即可,它应该可以工作。

You cannot set the background explicitly to white and then override it with a style-applied value. A style value is "weaker" than what is called a local value and will never override it. Just move your white background setting into the style as well and it should work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文