基于 ComboBox 选择覆盖默认样式的 WPF 按钮 IsEnabled

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/371879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:52:45  来源:igfitidea点击:

WPF Button IsEnabled Based on ComboBox Selection Overwriting default style

wpfxamlstylesisenabled

提问by Nate

I have a Button that is looking at 2 comboboxes to make sure they have a value before it is enabled. The problem is the way I am doing it is overwriting the default style declared in my theme project.

我有一个 Button 正在查看 2 个组合框,以确保它们在启用之前具有值。问题是我这样做的方式是覆盖我的主题项目中声明的默认样式。

<Button x:Name="btnOK" VerticalAlignment="Center" Content="OK" IsDefault="True"  Margin="0" Click="btnOK_Click">
                    <Button.Style>
                      <Style BasedOn="{StaticResource DefaultButton}">
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ElementName=ddlWageTypes, Path=SelectedItem}" Value="{x:Null}">
                                    <Setter Property="Button.IsEnabled" Value="false"/>
                                </DataTrigger>
                                <DataTrigger Binding="{Binding ElementName=ddlJobTitles, Path=SelectedItem}" Value="{x:Null}">
                                    <Setter Property="Button.IsEnabled" Value="false"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Button.Style>
                </Button>

I've tried adding BasedOn="{StaticResouce MyDefaultButtonStyleName}" to the style tag but it blows up at runtime.

我试过将 BasedOn="{StaticResouce MyDefaultButtonStyleName}" 添加到 style 标签,但它在运行时爆炸了。

The error is "'System.Windows.Style' value cannot be assigned to property 'Style' of object 'System.Windows.Controls.Button'. Can only base on a Style with target type that is base type 'IFrameworkInputElement'. Error at object 'System.Windows.Style' in markup file"

错误是“无法将‘System.Windows.Style’值分配给对象‘System.Windows.Controls.Button’的属性‘Style’。只能基于目标类型为‘IFrameworkInputElement’的样式。错误在标记文件中的对象“System.Windows.Style”处”

Is there a was to do this in XAML without overwriting default style.

是否可以在 XAML 中执行此操作而不覆盖默认样式。

EDIT: Code Sample Updated. I get an error on OKButtonStyle saying "Cannot add element to property 'Resources', because the property can have only one child element if it uses an explicit collection tag. Error at object 'System.Windows.Style' in markup file "

编辑:代码示例已更新。我在 OKButtonStyle 上收到一条错误消息,说“无法将元素添加到属性 'Resources',因为如果使用显式集合标记,该属性只能有一个子元素。标记文件中的对象 'System.Windows.Style' 出错”

<UserControl x:Class="UK.Budgeting.XBAP.ShiftDiff.NewFTEPremiumPaySummary"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:compModel="clr-namespace:System.ComponentModel;assembly=WindowsBase"
    xmlns:local="clr-namespace:UK.Budgeting.XBAP.ShiftDiff">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="CellTemplates.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

      <Style TargetType="{x:Type Button}" x:Key="OKButtonStyle" BasedOn="{StaticResource DefaultButton}">
        <Style.Triggers>
          <DataTrigger Binding="{Binding ElementName=ddlWageTypes, Path=SelectedItem}" Value="{x:Null}">
            <Setter Property="Button.IsEnabled" Value="false"/>
          </DataTrigger>
          <DataTrigger Binding="{Binding ElementName=ddlJobTitles, Path=SelectedItem}" Value="{x:Null}">
            <Setter Property="Button.IsEnabled" Value="false"/>
          </DataTrigger>
        </Style.Triggers>
      </Style>

    </UserControl.Resources>
    <Grid>
        <Rectangle Style="{StaticResource DialogRectangle}"/>
        <Border Style="{StaticResource DialogBorder}">
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Background="White">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition/>
                    <ColumnDefinition Width="5"/>
                    <ColumnDefinition MinWidth="300"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition/>
                    <RowDefinition Height="2"/>
                    <RowDefinition/>
                    <RowDefinition Height="2"/>
                    <RowDefinition/>
                    <RowDefinition Height="2"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>

                <TextBlock Grid.Column="0" Grid.Row="0" Style="{StaticResource LabelStyle}">Wage Type</TextBlock>
                <TextBlock Grid.Column="0" Grid.Row="2" Style="{StaticResource LabelStyle}">Job Title</TextBlock>

                <ComboBox x:Name="ddlWageTypes" VerticalAlignment="Top" Grid.Column="2" Grid.Row="0"
                          DisplayMemberPath="DisplayName"
                          SelectedValuePath="WageTypeCode"/>
                <ComboBox x:Name="ddlJobTitles" VerticalAlignment="Top" Grid.Column="2" Grid.Row="2"
                          DisplayMemberPath="JobTitle"
                          SelectedValuePath="JobCode"/>

                <StackPanel Grid.Column="2" Grid.Row="6" VerticalAlignment="Top" Orientation="Horizontal" Margin="5">
                  <Button x:Name="btnOK" VerticalAlignment="Center" Content="OK" IsDefault="True"  Margin="0" Click="btnOK_Click" Style="{StaticResource OKButtonStyle}"/>
                    <Button x:Name="btnCancel" VerticalAlignment="Center" Content="Cancel" IsCancel="True" Margin="10,0,0,0" Click="btnCancel_Click"/>
                </StackPanel>
            </Grid>
        </Border>
    </Grid>
</UserControl>

回答by Szymon Rozga

How is this

这怎么样

BasedOn="{StaticResouce DefaultButton}"

supposed to refer to the default button style? This crashes because DefaultButton is an undefined resource in your app.

应该参考默认按钮样式?这会崩溃,因为 DefaultButton 是您的应用程序中未定义的资源。

It should be:

它应该是:

BasedOn="{StaticResource {x:Type Button}}"

EDIT: Sorry, answered too hastily.

编辑:对不起,回答太仓促了。

I noticed now your button has a Style={} set, and is pointing to a style called OkBUttonStyle. This is the style that should define everything and be based on the default button style. By everything, I include those triggers. What you are saying in the XAML is that Style is the Content of your Button.

我注意到现在您的按钮设置了 Style={},并且指向一个名为 OkBUttonStyle 的样式。这是应该定义一切并基于默认按钮样式的样式。总而言之,我包括了这些触发器。您在 XAML 中所说的是样式是按钮的内容。

Maybe some code will help:

也许一些代码会有所帮助:

 <Window x:Class="WindowsApplication7.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WindowsApplication7" Height="300" Width="300"
    >
  <Window.Resources>
    <Style TargetType="{x:Type Button}" x:Key="defaultButtonStyle">
      <Setter Property="Background" Value="Red" />
    </Style>

    <Style TargetType="{x:Type Button}" x:Key="okButtonStyle" BasedOn="{StaticResource defaultButtonStyle}">
      <Setter Property="Foreground" Value="Green" />
      <Style.Triggers>
        <Trigger Property="IsEnabled" Value="True">
          <Setter Property="Background" Value="Yellow" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
          <Setter Property="Foreground" Value="Blue" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </Window.Resources>
  <StackPanel>
    <Button>System default</Button>
    <Button Style="{StaticResource defaultButtonStyle}">My Default</Button>
    <Button Style="{StaticResource okButtonStyle}">Ok</Button>
    <Button Style="{StaticResource okButtonStyle}" IsEnabled="False">Ok disabled</Button>
  </StackPanel>
</Window>