简体   繁体   English

如何禁用按钮并更改其颜色?

[英]How to disable a button and change it's color?

I have this code I found on here, that generates me a grid of buttons - I know this may not be the best way to do this, but for now I'd like to do it this way, I am quite new at this.我在这里找到了这段代码,它为我生成了一个按钮网格——我知道这可能不是最好的方法,但现在我想这样做,我对此很陌生。 So the button should be either Black ( 1 ) or White ( 0 ), depending on it's value.因此按钮应该是Black ( 1 ) 或White ( 0 ),具体取决于它的值。 This all works, until I hover the button and I can see it's value.这一切都有效,直到我按下 hover 按钮,我才能看到它的价值。 If I just add the Visibility property = "false" to the button, it does not even get displayed.如果我只是将Visibility属性 = "false" 添加到按钮,它甚至不会显示。

一个由黑色和白色按钮组成的网格,其中一个按钮悬停在其中,显示一个黑色的数字作为内容和带有蓝色边框的浅蓝色背景。

This is my code:这是我的代码:

<Window.Resources>
    <DataTemplate x:Key="DataTemplate_Level2">
        <Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1">
            <Button.Style>
                <Style TargetType="Button">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding}" Value="1">
                            <Setter Property="Background" Value="Black"/>
                            <Setter Property="Foreground" Value="Black" />
                        </DataTrigger>
                        <DataTrigger Binding="{Binding}" Value="0">
                            <Setter Property="Background" Value="White"/>
                            <Setter Property="Foreground" Value="White" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Button.Style>
        </Button>
    </DataTemplate>
    <DataTemplate x:Key="DataTemplate_Level1">
        <ItemsControl ItemsSource="{Binding}" ItemTemplate="{DynamicResource DataTemplate_Level2}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </DataTemplate>
</Window.Resources>

And then I display the grid here:然后我在这里显示网格:

<Grid Margin="10,10,10,-636" Grid.Row="3">
    <ItemsControl x:Name="automata" ItemTemplate="{DynamicResource DataTemplate_Level1}" Margin="0,0,0,-119"/>
</Grid>

I would also be happy of a recommendation on how to display these values in another way.我也很乐意就如何以另一种方式显示这些值提出建议。

If you want to change the appearance or visual states of a control, create a style with a ControlTemplate that fits your requirements.如果要更改控件的外观或视觉状态,请使用符合您要求的ControlTemplate创建样式。 You can also extract the default style using Blen or Visual Studio and adapt it.您还可以使用 Blen 或 Visual Studio 提取默认样式并进行调整。

In the following, I took the default style with its control template for Button and commented out the triggers for MouseOver , Pressed and other states so they are ineffective, but you still see where to continue since your question certainly is only the starting point for further customization.在下文中,我采用了Button的默认样式及其控件模板,并注释掉了MouseOverPressed和其他状态的触发器,因此它们无效,但您仍然看到继续的地方,因为您的问题当然只是进一步的起点定制。 I adapted and added your triggers to the ControlTemplate .我修改了您的触发器并将其添加到ControlTemplate中。 What this does is simply show a black button for 1 and white for 0 .它所做的只是为1显示一个黑色按钮,为0显示一个白色按钮。

<Style x:Key="MyButtonStyle" TargetType="{x:Type Button}">
   <Style.Resources>
      <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
      <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
      <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
      <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
      <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
      <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
      <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
      <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
      <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>
   </Style.Resources>
   <Setter Property="FocusVisualStyle">
      <Setter.Value>
         <Style>
            <Setter Property="Control.Template">
               <Setter.Value>
                  <ControlTemplate>
                     <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                  </ControlTemplate>
               </Setter.Value>
            </Setter>
         </Style>
      </Setter.Value>
   </Setter>
   <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
   <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="HorizontalContentAlignment" Value="Center"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Padding" Value="1"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type Button}">
            <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
               <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
            </Border>
            <ControlTemplate.Triggers>

               <!-- These are the default triggers, which you might customize to fit your style. -->
               <!--<Trigger Property="IsDefaulted" Value="true">
                  <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
               </Trigger>
               <Trigger Property="IsMouseOver" Value="true">
                  <Setter Property="Background" TargetName="border" Value="{StaticResource Button.MouseOver.Background}"/>
                  <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
               </Trigger>
               <Trigger Property="IsPressed" Value="true">
                  <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                  <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
               </Trigger>
               <Trigger Property="IsEnabled" Value="false">
                  <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                  <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                  <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
               </Trigger>-->

               <!-- These are your triggers, which now act on the Content property of the templated button. -->
               <DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="1">
                  <Setter Property="Background" Value="Black"/>
                  <Setter Property="Foreground" Value="Black" />
               </DataTrigger>
               <DataTrigger Binding="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}" Value="0">
                  <Setter Property="Background" Value="White"/>
                  <Setter Property="Foreground" Value="White" />
               </DataTrigger>

            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

Use this style in your data template and you should get the expected result.在您的数据模板中使用这种样式,您应该会得到预期的结果。

<DataTemplate x:Key="DataTemplate_Level2">
   <Button Content="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyButtonStyle}"/>
</DataTemplate>

Since you try to make the text 1 and 0 invisible by setting the background and foreground to the same color, you could also simply remove the ContentPresenter from the ControlTemplate , so there is no content displayed at all and the Foreground setters are not needed.由于您尝试通过将背景和前景设置为相同的颜色来使文本10不可见,因此您也可以简单地从ControlTemplate中删除ContentPresenter ,因此根本不会显示任何内容,也不需要Foreground设置器。

Another thing to note is that your binary state maybe suggests to use a ToggleButton instead.另一件需要注意的事情是,您的二进制文件 state 可能建议改用ToggleButton

Base class for controls that can switch states, such as CheckBox .基础 class 用于可以切换状态的控件,例如CheckBox

This is an example style for a ToggleButton that does not show content and sets the background like in your question, but dependening on its IsChecked property.这是ToggleButton的示例样式,它不显示内容并像您的问题一样设置背景,但取决于其IsChecked属性。

<Style x:Key="MyToggleButtonStyle" TargetType="{x:Type ToggleButton}">
   <Style.Resources>
      <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
      <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
   </Style.Resources>
   <Setter Property="FocusVisualStyle">
      <Setter.Value>
         <Style>
            <Setter Property="Control.Template">
               <Setter.Value>
                  <ControlTemplate>
                     <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                  </ControlTemplate>
               </Setter.Value>
            </Setter>
         </Style>
      </Setter.Value>
   </Setter>
   <Setter Property="Background" Value="{StaticResource Button.Static.Background}"/>
   <Setter Property="BorderBrush" Value="{StaticResource Button.Static.Border}"/>
   <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
   <Setter Property="BorderThickness" Value="1"/>
   <Setter Property="HorizontalContentAlignment" Value="Center"/>
   <Setter Property="VerticalContentAlignment" Value="Center"/>
   <Setter Property="Padding" Value="1"/>
   <Setter Property="Template">
      <Setter.Value>
         <ControlTemplate TargetType="{x:Type ToggleButton}">
            <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true"/>
            <ControlTemplate.Triggers>
               <Trigger Property="IsChecked" Value="True">
                  <Setter Property="Background" Value="Black"/>
               </Trigger>
               <Trigger Property="IsChecked" Value="False">
                  <Setter Property="Background" Value="White"/>
               </Trigger>
            </ControlTemplate.Triggers>
         </ControlTemplate>
      </Setter.Value>
   </Setter>
</Style>

Change the binding in your data template from Content to IsChecked .将数据模板中的绑定从Content更改为IsChecked

<DataTemplate x:Key="DataTemplate_Level2">
   <ToggleButton IsChecked="{Binding}" Height="15" Width="15" Margin="1,1,1,1" Style="{DynamicResource MyToggleButtonStyle}"/>
</DataTemplate>

This buys you the advantage of toggling the states automatically, but only if you can provide a property for two-way binding (getter and setter), otherwise an exception will be thrown.这为您带来了自动切换状态的优势,但前提是您可以为双向绑定(getter 和 setter)提供属性,否则将抛出异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM