【问题标题】:Change old WPF ProgressBar controltemplate to WPF4将旧的 WPF ProgressBar 控件模板更改为 WPF4
【发布时间】:2012-04-12 15:00:24
【问题描述】:

我想要在我的 WPF 应用程序中使用温度计,并在 MSDN magazine 中找到了一个模板


编辑开始

我找到了不起作用的原因:http://connect.microsoft.com/VisualStudio/feedback/details/571674/issue-with-vertical-progress-bar-on-4-0-framework

但是我/你呢?仍然需要弄清楚如何使它与 WPF4 一起工作。

编辑结束


控件看起来不错,但设置Value时似乎没有更新指标。

我已将其粘贴到 Kaxaml 中,并尝试了 VS2010。代码有问题还是我做错了什么?

<!-- ================================================
      ThermometerProgressBar.xaml by Charles Petzold
     ================================================ -->
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>

        <!-- Define template for thermometer progress bar -->
        <ControlTemplate x:Key="templateThermometer"
                         TargetType="{x:Type ProgressBar}">

            <!-- Define two brushes for the thermometer liquid -->
            <ControlTemplate.Resources>
                <LinearGradientBrush x:Key="brushStem"
                                     StartPoint="0 0" EndPoint="1 0">
                    <GradientStop Offset="0" Color="Red" />
                    <GradientStop Offset="0.3" Color="Pink" />
                    <GradientStop Offset="1" Color="Red" />
                </LinearGradientBrush>

                <RadialGradientBrush x:Key="brushBowl"
                                     GradientOrigin="0.3 0.3">
                    <GradientStop Offset="0" Color="Pink" />
                    <GradientStop Offset="1" Color="Red" />                        
                </RadialGradientBrush>
            </ControlTemplate.Resources>

            <!-- Two-row Grid divides thermometer into stem and bowl -->
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="*" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>

                <!-- Second grid divides stem area in three columns -->
                <Grid Grid.Row="0">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25*" />
                        <ColumnDefinition Width="50*" />
                        <ColumnDefinition Width="25*" />
                    </Grid.ColumnDefinitions>

                    <!-- This border displays the stem -->
                    <Border Grid.Column="1" BorderBrush="SteelBlue" 
                            BorderThickness="3 3 3 0"
                            CornerRadius="6 6 0 0" >

                        <!-- Track and Indicator elements -->
                        <Decorator Name="PART_Track">
                            <Border Name="PART_Indicator"
                                    CornerRadius="6 6 0 0"
                                    VerticalAlignment="Bottom"
                                    Background="{StaticResource brushStem}" />
                        </Decorator>
                    </Border>
                </Grid>

                <!-- The bowl outline goes in the main Grid second row -->
                <Ellipse Grid.Row="1"
                         Width="{TemplateBinding Width}"
                         Height="{TemplateBinding Width}"
                         Stroke="SteelBlue" StrokeThickness="3" />

                <!-- Another grid goes in the same cell -->
                <Grid Grid.Row="1" >
                    <Grid.RowDefinitions>
                        <RowDefinition Height="50*" />
                        <RowDefinition Height="50*" />
                    </Grid.RowDefinitions>

                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25*" />
                        <ColumnDefinition Width="50*" />
                        <ColumnDefinition Width="25*" />
                    </Grid.ColumnDefinitions>

                    <!-- This is to close up the gap between bowl and stem -->
                    <Border Grid.Row="0" Grid.Column="1"
                            BorderBrush="SteelBlue"
                            BorderThickness="3 0 3 0"
                            Background="{StaticResource brushStem}" />
                </Grid>

                <!-- Another ellipse to fill up the bowl -->
                <Ellipse Grid.Row="1"
                         Width="{TemplateBinding Width}"
                         Height="{TemplateBinding Width}"
                         Stroke="Transparent" StrokeThickness="6"
                         Fill="{StaticResource brushBowl}" />
            </Grid>
        </ControlTemplate>
    </Page.Resources>

    <StackPanel>

        <!-- Create Thermometer ProgressBar -->
        <ProgressBar Template="{StaticResource templateThermometer}" 
                     Orientation="Vertical" Minimum="0" Maximum="100"
                     Width="50" Height="350" Margin="50" 
                     Value="{Binding ElementName=scroll, Path=Value}" />

        <!-- ScrollBar to simulate progress -->
        <ScrollBar Name="scroll" Orientation="Horizontal" 
                   Minimum="0" Maximum="100"
                   SmallChange="1" LargeChange="10" 
                   Margin="50 0 50 0" />

        <TextBlock Text="Manipulate ScrollBar to test ProgressBar"
                   HorizontalAlignment="Center" />
    </StackPanel>
</Page>

【问题讨论】:

  • 你是如何绑定 Value 属性的?
  • 你是这个意思吗?插入代码底部的 Value="{Binding ElementName=scroll, Path=Value}"
  • 对我来说它正在工作。如果我更改滚动条。我已经使用 Windows 窗体完成了示例
  • @Karsten 是的,我的意思是,确保绑定正确
  • 我不关注你。绑定错了吗?无论哪种方式,我都尝试直接设置 Value

标签: wpf wpf-4.0


【解决方案1】:

我发现你需要添加一个模板触发器来在方向属性设置为 "Vertical" 时触发。我对代码进行了一些更改,并且工作正常。

<!-- Define template for thermometer progress bar -->
<ControlTemplate x:Key="ThermometerProgressBarStyle"
                     TargetType="{x:Type ProgressBar}">

    <!-- Define two brushes for the thermometer liquid -->
    <ControlTemplate.Resources>
        <LinearGradientBrush x:Key="brushStem"
                                 StartPoint="0 0" EndPoint="1 0">
            <GradientStop Offset="0" Color="Red" />
            <GradientStop Offset="0.3" Color="Pink" />
            <GradientStop Offset="1" Color="Red" />
        </LinearGradientBrush>
        <LinearGradientBrush x:Key="brushStemVertical"
                                 StartPoint="0 0" EndPoint="0 1">
            <GradientStop Offset="0" Color="Red" />
            <GradientStop Offset="0.3" Color="Pink" />
            <GradientStop Offset="1" Color="Red" />
        </LinearGradientBrush>
        <RadialGradientBrush x:Key="brushBowl"
                                 GradientOrigin="0.3 0.3">
            <GradientStop Offset="0" Color="Pink" />
            <GradientStop Offset="1" Color="Red" />
        </RadialGradientBrush>
    </ControlTemplate.Resources>

    <!-- Two-row Grid divides thermometer into stem and bowl -->
    <Grid ShowGridLines="False">
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <!-- Second grid divides stem area in three columns -->
        <Grid Grid.Row="0" ShowGridLines="false">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="50*" />
                <ColumnDefinition Width="25*" />
            </Grid.ColumnDefinitions>
            <!-- This border displays the stem -->
                <!-- Track and Indicator elements -->

            <Border Grid.Column="1" BorderBrush="SteelBlue" 
                    BorderThickness="0 3 3 3"
                    CornerRadius="0 6 6 0"
                           Name="border">
                    <Grid>
                        <Rectangle Fill="{TemplateBinding Background}"
                                      Name="PART_Track" />
                        <Rectangle Name="PART_Indicator"
                            Fill="{StaticResource brushStemVertical }"
                               HorizontalAlignment="Left"/>
                    </Grid>
                </Border>
        </Grid>
        <!-- The bowl outline goes in the main Grid second row -->
        <Ellipse Grid.Row="1"
                     Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Width}"
                     Stroke="SteelBlue" StrokeThickness="3" />
        <!-- Another grid goes in the same cell -->
        <Grid Grid.Row="1" >
            <Grid.RowDefinitions>
                <RowDefinition Height="50*" />
                <RowDefinition Height="50*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="50*" />
                <ColumnDefinition Width="25*" />
            </Grid.ColumnDefinitions>
            <!-- This is to close up the gap between bowl and stem -->
            <Border Grid.Row="0" Grid.Column="1"
                        BorderBrush="SteelBlue"
                        BorderThickness="3 0 3 0"
                        Background="{StaticResource brushStem}" />
        </Grid>
        <!-- Another ellipse to fill up the bowl -->
        <Ellipse Grid.Row="1"
                     Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Width}"
                     Stroke="Transparent" StrokeThickness="6"
                     Fill="{StaticResource brushBowl}" />
    </Grid>

    <!--add Orientation trigger-->
    <ControlTemplate.Triggers>
        <Trigger Property="Orientation" Value="Vertical">
            <Setter TargetName="border" Property="LayoutTransform">
                <Setter.Value>
                    <RotateTransform Angle="-90" />
                </Setter.Value>
            </Setter>
        </Trigger>
    </ControlTemplate.Triggers>    
</ControlTemplate>

【讨论】:

    【解决方案2】:
    <Window x:Class="WpfApplication44.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="518" Width="542">
    <Window.Resources>
    <!-- Define template for thermometer progress bar -->
    <ControlTemplate x:Key="templateThermometer"
                     TargetType="{x:Type ProgressBar}">
    
        <!-- Define two brushes for the thermometer liquid -->
        <ControlTemplate.Resources>
            <LinearGradientBrush x:Key="brushStem"
                                 StartPoint="0 0"
                                 EndPoint="1 0">
                <GradientStop Offset="0"
                              Color="Red" />
                <GradientStop Offset="0.3"
                              Color="Pink" />
                <GradientStop Offset="1"
                              Color="Red" />
            </LinearGradientBrush>
    
            <RadialGradientBrush x:Key="brushBowl"
                                 GradientOrigin="0.3 0.3">
                <GradientStop Offset="0"
                              Color="Pink" />
                <GradientStop Offset="1"
                              Color="Red" />
            </RadialGradientBrush>
        </ControlTemplate.Resources>
    
        <!-- Two-row Grid divides thermometer into stem and bowl -->
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="*" />
                <RowDefinition Height="Auto" />
            </Grid.RowDefinitions>
    
            <!-- Second grid divides stem area in three columns -->
            <Grid Grid.Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="25*" />
                    <ColumnDefinition Width="50*" />
                    <ColumnDefinition Width="25*" />
                </Grid.ColumnDefinitions>
    
                <!-- This border displays the stem -->
                <Border Grid.Column="1"
                        BorderBrush="SteelBlue"
                        BorderThickness="3 3 3 0"
                        CornerRadius="6 6 0 0">
    
                    <!-- Track and Indicator elements -->
                    <Decorator Name="PART_Track">
                        <Border Name="PART_Indicator"
                                CornerRadius="6 6 0 0"
                                VerticalAlignment="Bottom"
                                Background="{StaticResource brushStem}" />
                    </Decorator>
                </Border>
            </Grid>
    
            <!-- The bowl outline goes in the main Grid second row -->
            <Ellipse Grid.Row="1"
                     Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Width}"
                     Stroke="SteelBlue"
                     StrokeThickness="3" />
    
            <!-- Another grid goes in the same cell -->
            <Grid Grid.Row="1">
                <Grid.RowDefinitions>
                    <RowDefinition Height="50*" />
                    <RowDefinition Height="50*" />
                </Grid.RowDefinitions>
    
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="25*" />
                    <ColumnDefinition Width="50*" />
                    <ColumnDefinition Width="25*" />
                </Grid.ColumnDefinitions>
    
                <!-- This is to close up the gap between bowl and stem -->
                <Border Grid.Row="0"
                        Grid.Column="1"
                        BorderBrush="SteelBlue"
                        BorderThickness="3 0 3 0"
                        Background="{StaticResource brushStem}" />
            </Grid>
    
            <!-- Another ellipse to fill up the bowl -->
            <Ellipse Grid.Row="1"
                     Width="{TemplateBinding Width}"
                     Height="{TemplateBinding Width}"
                     Stroke="Transparent"
                     StrokeThickness="6"
                     Fill="{StaticResource brushBowl}" />
        </Grid>
    </ControlTemplate>
    </Window.Resources>
    
    <StackPanel>
    
        <!-- Create Thermometer ProgressBar -->
        <ProgressBar Template="{StaticResource templateThermometer}"
                     Orientation="Vertical"
                     Minimum="0"
                     Maximum="100"
                     Width="50"
                     Height="350"
                     Margin="50"
                     Value="{Binding ElementName=scroll, Path=Value}" />
    
        <!-- ScrollBar to simulate progress -->
        <ScrollBar Name="scroll"
                   Orientation="Horizontal"
                   Minimum="0"
                   Maximum="100"
                   Value="20"
                   SmallChange="1"
                   LargeChange="10"
                   Margin="50 0 50 0" />
    
        <TextBlock Text="Manipulate ScrollBar to test ProgressBar"
                   HorizontalAlignment="Center" />
    </StackPanel>
    

    【讨论】:

      猜你喜欢
      • 2011-09-08
      • 2011-03-20
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多