Wpf 调试XAML和vb中的资源值问题?
我有一个看似简单的问题:制作一个可以处理任何分辨率显示的应用程序 背景: 这是一个仅显示的应用程序(无用户界面)。它是用来显示信息的,我制作了一个测试应用程序来解决一个问题。我花了几天时间试图找到解决这个小问题的办法。要么需要一个聪明的编程解决方案(到目前为止我还没有找到),要么需要一种不同的方法来解决这个问题(同样,一直很难找到) 这是一个WPF应用程序,后面有VB.net代码。“唯一”窗口的组成需要保持与显示组件相同的相对布局,并且应用程序打算全屏运行(此演示在窗口中运行,因此我可以轻松调整其大小并测试不同的“屏幕布局”) 除了布局的一部分外,其他部分都可以正常工作 出现问题的部分是一个“条”,用于根据情况向上或向下设置动画。根据应用程序窗口的大小,条形图的大小已经发生了相应的更改。然而。。。杆移动的距离取决于该杆的大小;它越短,需要移动的像素就越少,相反,更高分辨率的屏幕需要它进一步移动。动画是通过更改栅格对象的高度来完成的,栅格对象包含矩形(条形图)和视口,而视口又包含textblock对象 我在XAML中创建了一个资源值,该值表示包含条的网格对象的默认高度。如果该资源作为静态资源绑定到关键帧的值,则该值将传递到情节提要,并发生动画。但是,我无法更改此配置中的值。当窗口的大小改变时,VB代码试图改变资源键值,但没有乐趣。我们也尝试过将绑定作为动态资源进行 大量阅读表明,一些绑定到XAML的工作正常,而其他绑定(如关键帧)则没有那么幸运;关于“自由化”,这似乎很愚蠢,因为这不应该那么难。我读到的其他东西表明,“修复”是在代码背后实现解决方案。大多数人没有提供任何其他信息来说明如何做到这一点,而其他几项建议方法似乎荒谬地迂回 以下是XAML,其中包含一些内联注释以指出发生了什么:Wpf 调试XAML和vb中的资源值问题?,wpf,vb.net,xaml,animation,Wpf,Vb.net,Xaml,Animation,我有一个看似简单的问题:制作一个可以处理任何分辨率显示的应用程序 背景: 这是一个仅显示的应用程序(无用户界面)。它是用来显示信息的,我制作了一个测试应用程序来解决一个问题。我花了几天时间试图找到解决这个小问题的办法。要么需要一个聪明的编程解决方案(到目前为止我还没有找到),要么需要一种不同的方法来解决这个问题(同样,一直很难找到) 这是一个WPF应用程序,后面有VB.net代码。“唯一”窗口的组成需要保持与显示组件相同的相对布局,并且应用程序打算全屏运行(此演示在窗口中运行,因此我可以轻松调整
<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