带有触发器的 WPF 设计时与运行时样式差异

Posted

技术标签:

【中文标题】带有触发器的 WPF 设计时与运行时样式差异【英文标题】:WPF Design-Time vs Run-Time Style Differences with Triggers 【发布时间】:2011-06-03 13:03:51 【问题描述】:

我对如何在设计时与运行时呈现 XAML 有一个大问题。在大多数情况下,事情是一致的,但是当我使用任何具有触发器的样式时,触发器不会在设计时检查。

这是一个示例应用程序,用于展示事物的不同显示方式:

<Window x:Class="DesignDifferencesWithDesignAndRuntime.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="400" Width="400">
<Window.Resources>
    <Style x:Key="multiLineInTrigger" TargetType="x:Type TextBox">
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="Width" Value="150" />
        <Setter Property="Height" Value="22" />
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Style.Triggers>
            <Trigger Property="AcceptsReturn" Value="True">
                <Setter Property="Width" Value="Auto" />
                <Setter Property="Height" Value="Auto" />
                <Setter Property="HorizontalAlignment" Value="Stretch" />
                <Setter Property="VerticalAlignment" Value="Stretch" />
            </Trigger>
        </Style.Triggers>
    </Style>
    <Style x:Key="singleLineInTrigger" TargetType="x:Type TextBox">
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="Width" Value="Auto" />
        <Setter Property="Height" Value="Auto" />
        <Setter Property="HorizontalAlignment" Value="Stretch" />
        <Setter Property="VerticalAlignment" Value="Stretch" />
        <Setter Property="BorderBrush" Value="Blue" />
        <Setter Property="BorderThickness" Value="2" />
        <Style.Triggers>
            <Trigger Property="AcceptsReturn" Value="False">
                <Setter Property="Width" Value="150" />
                <Setter Property="Height" Value="22" />
                <Setter Property="HorizontalAlignment" Value="Left" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Trigger>
        </Style.Triggers>
    </Style>   
    <Style TargetType="x:Type TextBlock">
        <Setter Property="FontWeight" Value="Bold" />
        <Setter Property="HorizontalAlignment" Value="Right" />
    </Style>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="150" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <TextBlock Text="Single (Single Style)" Grid.Row="0" Grid.Column="0" />
    <TextBlock Text="Single (Multi Style)" Grid.Row="1" Grid.Column="0" />
    <TextBlock Text="Multi (Single Style)" Grid.Row="2" Grid.Column="0" />
    <TextBlock Text="Multi (Multi Style)" Grid.Row="3" Grid.Column="0" />

    <TextBox Grid.Row="0" Grid.Column="1" Style="StaticResource singleLineInTrigger" />
    <TextBox Grid.Row="1" Grid.Column="1" Style="StaticResource multiLineInTrigger" />
    <TextBox Grid.Row="2" Grid.Column="1" Style="StaticResource singleLineInTrigger" AcceptsReturn="True" />
    <TextBox Grid.Row="3" Grid.Column="1" Style="StaticResource multiLineInTrigger" AcceptsReturn="True" />
</Grid>

我创建了两个独立的 TextBox 样式,它们的作用完全相同。当 TextBox 是单行(AcceptsReturn = False)时,我需要宽度为 150,高度为 22。当它是多行时(AcceptsReturn = True,显然)我需要宽度和高度来拉伸和取整个空间。

这两个触发器在运行时都可以正常工作,正如运行此代码所显示的那样,但在设计时,它们都无法在触发条件下工作。当使用“multiLineInTrigger”样式时,文本框的高度和宽度将静态设置(与 AcceptsReturn 无关),但当使用“singleLineInTrigger”样式时,无论 AcceptsReturn 值如何,控件都会被拉伸。

这个问题有解决方案吗?这对开发团队来说变得相当麻烦和耗时,因为他们不知道它什么时候工作,什么时候不工作,直到编译和运行应用程序(这是一个漫长的过程)。

谢谢。

【问题讨论】:

设计时间假设是您引用的是 VS2010 还是 Expression Blend? 1) 尝试重新构建解决方案并检查,这是第一个选项。 2) 通过从 TextBox 子类创建一个 CustomTextBox。在 OnApplyTemplate 中,在代码块 DesignerProperties.GetIsInDesignMode() 中应用此样式。因此,这种风格将单独应用于设计模式。使用此自定义文本框。你完成了。 @Aaron,是的,这是在 Visual Studio 2010 中,而不是表达式。 @Prince Ashitaka,我尝试重建解决方案,但无济于事。我们已经有一些自定义控件,我将尝试处理 OnApplyTemplate 并使用您的解决方案。这是唯一的解决方案吗?我真的不认为管理层会很乐意为我们用来处理此事件的所有不同控件制作自定义控件。谢谢你的信息。 【参考方案1】:

我已多次看到此问题,但从未见过解决方法,触发器在 Visual Studio 2010 Designer 中不起作用。希望他们能尽快解决这个问题。

我能想到的唯一解决方案是在 Expression Blend 4 中进行设计工作,而不是完美地工作。可能不太理想,但目前我认为您没有其他选择

【讨论】:

我担心可能是这种情况。感谢您提供的信息,我会检查一下表达式混合,看看这是否是一个解决方案。

以上是关于带有触发器的 WPF 设计时与运行时样式差异的主要内容,如果未能解决你的问题,请参考以下文章

Flink 1.13,面向流批一体的运行时与 DataStream API 优化

Flink 1.13,面向流批一体的运行时与 DataStream API 优化

带有 LiveCharts 的 WPF 在运行时添加带有 DataBinding 的系列

UISearchBar 在活动时与 UITableView 内容重叠

WPF学习第三十七章 触发器

java编译时与运行时概念与实例详解 -------------------(*************************)