Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 调试XAML和vb中的资源值问题?_Wpf_Vb.net_Xaml_Animation - Fatal编程技术网

Wpf 调试XAML和vb中的资源值问题?

Wpf 调试XAML和vb中的资源值问题?,wpf,vb.net,xaml,animation,Wpf,Vb.net,Xaml,Animation,我有一个看似简单的问题:制作一个可以处理任何分辨率显示的应用程序 背景: 这是一个仅显示的应用程序(无用户界面)。它是用来显示信息的,我制作了一个测试应用程序来解决一个问题。我花了几天时间试图找到解决这个小问题的办法。要么需要一个聪明的编程解决方案(到目前为止我还没有找到),要么需要一种不同的方法来解决这个问题(同样,一直很难找到) 这是一个WPF应用程序,后面有VB.net代码。“唯一”窗口的组成需要保持与显示组件相同的相对布局,并且应用程序打算全屏运行(此演示在窗口中运行,因此我可以轻松调整

我有一个看似简单的问题:制作一个可以处理任何分辨率显示的应用程序

背景: 这是一个仅显示的应用程序(无用户界面)。它是用来显示信息的,我制作了一个测试应用程序来解决一个问题。我花了几天时间试图找到解决这个小问题的办法。要么需要一个聪明的编程解决方案(到目前为止我还没有找到),要么需要一种不同的方法来解决这个问题(同样,一直很难找到)

这是一个WPF应用程序,后面有VB.net代码。“唯一”窗口的组成需要保持与显示组件相同的相对布局,并且应用程序打算全屏运行(此演示在窗口中运行,因此我可以轻松调整其大小并测试不同的“屏幕布局”)

除了布局的一部分外,其他部分都可以正常工作

出现问题的部分是一个“条”,用于根据情况向上或向下设置动画。根据应用程序窗口的大小,条形图的大小已经发生了相应的更改。然而。。。杆移动的距离取决于该杆的大小;它越短,需要移动的像素就越少,相反,更高分辨率的屏幕需要它进一步移动。动画是通过更改栅格对象的高度来完成的,栅格对象包含矩形(条形图)和视口,而视口又包含textblock对象

我在XAML中创建了一个资源值,该值表示包含条的网格对象的默认高度。如果该资源作为静态资源绑定到关键帧的值,则该值将传递到情节提要,并发生动画。但是,我无法更改此配置中的值。当窗口的大小改变时,VB代码试图改变资源键值,但没有乐趣。我们也尝试过将绑定作为动态资源进行

大量阅读表明,一些绑定到XAML的工作正常,而其他绑定(如关键帧)则没有那么幸运;关于“自由化”,这似乎很愚蠢,因为这不应该那么难。我读到的其他东西表明,“修复”是在代码背后实现解决方案。大多数人没有提供任何其他信息来说明如何做到这一点,而其他几项建议方法似乎荒谬地迂回

以下是XAML,其中包含一些内联注释以指出发生了什么:

<Window x:Name="SmartClock" x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">

    <Window.Resources>

        <!-- Set a variable (resource) to be used as the height value in animation -->
        <System:Double x:Key="OnAirBarUp">84</System:Double>

        <!-- Simple keyframe animation, which slides a bar with text into view -->
        <Storyboard x:Key="story_OnAirUp" x:Name="OnAirUp">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid_OnAir">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>

                <!-- ******  HERE'S WHERE THE "FUN" BEGINS   :/ 
                   This line needs to have a target value which changes, depending on the
                   height of objects in the window, and those are affected by the size
                   of the window.  The intention is to make this a full-screen app, but
                   can be used on many different monitors, so the resolution is not known
                   at design time.
                   The resource I set earlier in the XAML ("84") will be used for this
                   keyframe value, and the animation works... but is only "correct" for
                   the default window size.
                   (yes, I know that the bar starts in the "up" position currently, but that
                   is just to help me see it as I debug this... when the button is pushed,
                   the bar should instantly disappear, and then slide back on to the screen
                   to the same position).
                   *************************************************************************** -->
                <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="{StaticResource ResourceKey=OnAirBarUp}"/>


            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>

    <!-- Animation is triggered by clicking the button -->
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button1">
            <BeginStoryboard Storyboard="{StaticResource story_OnAirUp}"/>
        </EventTrigger>
    </Window.Triggers>


    <!-- Here we setup the page -->
    <Grid x:Name="grid_Page" ShowGridLines="True" >
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="4*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <!-- This is "status" grid at the top of the page -->
        <Grid x:Name="grid_Top" Grid.Row="0" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin" ShowGridLines="True" >
            <Grid.RowDefinitions>
                <RowDefinition Name="row_ProgramName" Height="1*"/>
                <RowDefinition Name="row_Status" Height="1*"/>
            </Grid.RowDefinitions>
            <Viewbox x:Name="viewbox_ProgramName" Grid.Row=" 0" Margin="0"  Stretch="Uniform">
                <TextBlock x:Name="textblock_ProgramName" Text="Some text on top" Background="#FFFFFF12"/>
            </Viewbox>

            <!-- This creates a grid which will hold the "ON AIR" bar -->
            <Grid x:Name="grid_OnAir" Grid.Row="1" VerticalAlignment="Bottom" ShowGridLines="True" Height="84" >
                <Rectangle x:Name="rectangle_OnAir"  Fill="#FF90A436" RadiusX="20" RadiusY="20" Margin="10,0" Height="83"/>
                <Viewbox x:Name="viewbox_OnAir" Grid.Row="1" Margin="0" Stretch="Uniform">
                    <TextBlock  x:Name="textblock_OnAir"  Text="ON AIR" FontSize="64" VerticalAlignment="Top" FontWeight="Bold" Background="#FFDC0000" Margin="0" HorizontalAlignment="Center" />
                </Viewbox>
            </Grid>
        </Grid>

        <!-- This is a big ugly button for triggering the storyboard -->
        <Button x:Name="button1" Content="Button" Margin="0" Grid.Row="1" FontSize="26.667" HorizontalAlignment="Left" Width="257"/>

    </Grid>

</Window>
这是许多排列的一个版本

当代码在不重新调整窗口大小的情况下运行时,如下所示:

使窗口大于默认值会对动画产生相反的效果;该杆位于着陆位置下方

我曾考虑将整个显示包装在一个viewbox控件中,这样整个混乱可以缩放以适应任何显示,并尝试了其中一些方法,但效果不太理想。它过于复杂,而且图形和文本中存在扭曲

从我所能做的故障排除来看,似乎资源值确实改变了,但绑定点的值没有改变;我几乎被应用程序启动时使用的任何值所困扰

为动态可配置的布局和广泛的动画功能提供一个框架,然后由于无法将这两个方面“很好地发挥”在一起而使其束手无策,这似乎很奇怪,因为一个简单的双精度值无法从代码传递到布局标记

请原谅邮件的长度;我试图做到彻底,并试图预测有人会写些什么作为回应。另外,请原谅样品的可怕颜色——在本测试的布局过程中,这对我来说是一种帮助,而不是用于最终应用

理想情况下,最好的解决方案将允许任何大小的显示,而程序对该分辨率没有任何先见之明。此外,在程序执行期间能够调整大小也很好,以防程序(毕竟)可以在不全屏幕的情况下使用。在这种情况下,它需要能够优雅地处理最合理的窗口大小(我必须对窗口大小进行一些下限编码)


无论我使用什么解决方案,它都需要能够处理其他类似的动画需求(其他部分需要在屏幕上和屏幕下移动,根据给定的情况移动正确的数量)。

我昨晚在Stack Overflow和on上都发布了这篇文章,并在MSDN上得到了很好的回复。这为我指明了正确的方向,我发布了一条后续消息,详细描述了对我有用的东西。以下是后续报告:


安迪

感谢您快速而详细的回复

我将从这部分开始:它现在可以工作了。

我确实花了几个小时摸索(利用你的线索)才到达那里。我当时(大约四个小时前)就开始了这个回复,但是坚持得到了回报

-------------

你说:“我知道你是在给这个条设置动画,但不是它的相对位置,以及它的来去方向。”

我猜你的意思是字面上的,比如屏幕上的位置,而不是概念上的(比如目的)

文字“where”是使条从屏幕的中间三分之一(大约)区域(水平分割)升起。整个应用程序是一个时钟,具有一些增值功能,可用于新闻编辑室。我已经有了一个基于这种设计的工作时钟,但是“空中”栏还没有实现。这将由网络套接字连接上的事件触发,确切地说,是在工作室“直播”时。当这种情况发生时,屏幕上三分之一的文本会随着“直播”栏的上升而优雅地收缩,基本上是进入上三分之一区域的一半

如果我不使用r,动画将正常工作
Class MainWindow

    Private Sub MainWindow_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged

        ' Set the size of items on the screen based on the size of the window.
        '  "rectangle_OnAir" is the rectangle (the "On-Air" bar for the display)
        '  "viewbox_OnAir" allows the textblock to properly scale.
        '  "grid_OnAir" is the container which will be made taller and shorter
        '     through animating the "height" property.  This allows the contents
        '     to slide up and down in their region of the screen.
        '     Since the window can be any size, we adjust the height of the
        '     controls to accomodate.
        rectangle_OnAir.Height = grid_Top.ActualHeight / 2
        viewbox_OnAir.Height = grid_Top.ActualHeight / 2
        grid_OnAir.Height = grid_Top.ActualHeight / 2

        ' Set the height of the dynamic resource "OnAirBarUp" to a value
        ' which equals the height of "rectangle_OnAir".
        ' This will be used in the animation to allow the whole rectangle to
        ' be displayed.
        Resources("OnAirBarUp") = grid_Top.ActualHeight / 2

    End Sub

End Class
    Inherits Window
    Public Sub New()
        InitializeComponent()
    End Sub
    Private SBMarquee As Storyboard
    Private XAnimation As DoubleAnimation
    Private Sub Window_ContentRendered(sender As Object, e As EventArgs)
        SBMarquee = TryCast(Me.Resources("SBmarquee"), Storyboard)
        XAnimation = TryCast(SBMarquee.Children(0), DoubleAnimation)
        XAnimation.[To] = MarqueeContainer.ActualWidth * -1
        AddHandler Me.SizeChanged, AddressOf Window_SizeChanged
    End Sub
    Private Sub Window_SizeChanged(sender As Object, e As SizeChangedEventArgs)
        XAnimation.[To] = MarqueeContainer.ActualWidth * -1
        MarqueeContainer.Visibility = Visibility.Hidden
        SBMarquee.Begin()
        MarqueeContainer.Visibility = Visibility.Visible
    End Sub
End Class
Imports System.Windows.Media.Animation
Private story_OnAirUp As Storyboard
Private keyframe_OnAirUp As EasingDoubleKeyFrame
Private Sub Window_ContentRendered(sender As Object, e As EventArgs)
    story_OnAirUp = TryCast(Me.Resources("story_OnAirUp"), Storyboard)
    keyframe_OnAirUp = TryCast(story_OnAirUp.Children(1), EasingDoubleKeyFrame)
    keyframe_OnAirUp.Value = grid_Top.ActualHeight / 2
    AddHandler Me.SizeChanged, AddressOf MainWindow_SizeChanged
End Sub
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid_OnAir">
timeline_OnAirUp.KeyFrames(1).Value = grid_Top.ActualHeight / 2
<Window x:Name="SmartClock" x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication3"
        xmlns:System="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Title="MainWindow" Height="600" Width="800">

    <Window.Resources>

        <!-- Simple keyframe animation, which slides a bar with text into view -->
        <Storyboard x:Key="story_OnAirUp" x:Name="OnAirUp">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="grid_OnAir">
                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>

                <!-- **** This is the keyframe which has a changed value from the VB code -->
                <EasingDoubleKeyFrame KeyTime="0:0:0.6" Value="84"/>

            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Window.Resources>

    <!-- Animation is triggered by clicking the button -->
    <Window.Triggers>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button1">
            <BeginStoryboard Storyboard="{StaticResource story_OnAirUp}"/>
        </EventTrigger>
    </Window.Triggers>

    <!-- Here we setup the page -->
    <Grid x:Name="grid_Page" ShowGridLines="True" >
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"/>
            <RowDefinition Height="4*"/>
            <RowDefinition Height="3*"/>
        </Grid.RowDefinitions>

        <!-- This is "status" grid at the top of the page -->
        <Grid x:Name="grid_Top" Grid.Row="0" d:LayoutOverrides="LeftMargin, RightMargin, TopMargin, BottomMargin" ShowGridLines="True" >
            <Grid.RowDefinitions>
                <RowDefinition Name="row_ProgramName"/>
                <RowDefinition Name="row_Status" Height="Auto"/>
            </Grid.RowDefinitions>
            <Viewbox x:Name="viewbox_ProgramName" Grid.Row=" 0" Margin="0"  Stretch="Uniform">
                <TextBlock x:Name="textblock_ProgramName" Text="Some text on top" Background="#FFFFFF12"/>
            </Viewbox>

            <!-- This creates a grid which will hold the "ON AIR" bar -->
            <Grid x:Name="grid_OnAir" Grid.Row="1" VerticalAlignment="Bottom" ShowGridLines="True" Height="84" >
                <Rectangle x:Name="rectangle_OnAir"  Fill="#FF90A436" RadiusX="20" RadiusY="20" Margin="10,0" Height="83"/>
                <Viewbox x:Name="viewbox_OnAir" Grid.Row="1" Margin="0" Stretch="Uniform">
                    <TextBlock  x:Name="textblock_OnAir"  Text="ON AIR" FontSize="64" VerticalAlignment="Top" FontWeight="Bold" Background="#FFDC0000" Margin="0" HorizontalAlignment="Center" />
                </Viewbox>
            </Grid>
        </Grid>

        <!-- This is a big ugly button for triggering the storyboard -->
        <Button x:Name="button1" Content="Button" Margin="0" Grid.Row="1" FontSize="26.667" HorizontalAlignment="Left" Width="257"/>

    </Grid>

</Window>
Imports System.Windows.Media.Animation

Class MainWindow

    Public Sub New()
        InitializeComponent()
    End Sub

    Private story_OnAirUp As Storyboard
    Private timeline_OnAirUp As DoubleAnimationUsingKeyFrames

    Private Sub MainWindow_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged

        ' These next three lines were moved from the "ContentRendered" section
        story_OnAirUp = TryCast(Me.Resources("story_OnAirUp"), Storyboard)
        timeline_OnAirUp = TryCast(story_OnAirUp.Children(0), DoubleAnimationUsingKeyFrames)
        timeline_OnAirUp.KeyFrames(1).Value = grid_Top.ActualHeight / 2

        rectangle_OnAir.Height = grid_Top.ActualHeight / 2
        viewbox_OnAir.Height = grid_Top.ActualHeight / 2
        grid_OnAir.Height = grid_Top.ActualHeight / 2

        ' This is the line which actually sets the value to the animation keyframe.
        timeline_OnAirUp.KeyFrames(1).Value = grid_Top.ActualHeight / 2

    End Sub

End Class