我想要实现像
这样的东西|图像(40%宽度)|文本(60%宽度)|
适应像
这样的小屏幕 |图像(100%)|
|文字(100%|
我使用AdaptiveTrigger和Grid获得了以下解决方案。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="NarrowView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Image.(Grid.ColumnSpan)" Value="2" />
<Setter Target="Text.(Grid.Row)" Value="1" />
<Setter Target="Text.(Grid.Column)" Value="0" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="860" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Image.(Grid.ColumnSpan)" Value="1" />
<Setter Target="Text.(Grid.Row)" Value="0" />
<Setter Target="Text.(Grid.Column)" Value="1" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="Image" Source="../Image.jpg" />
<TextBlock x:Name="Text" Grid.Column="1" TextWrapping="WrapWholeWords" Text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum." />
<Border Grid.Row="2" Grid.ColumnSpan="2" Background="Blue">
<TextBlock Text="Other Content" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</Grid>
我的问题:
Windows 10 UWP Apps提供的新Realtive Panel是否有类似的解决方案?
答案 0 :(得分:1)
让我们运用我对x:Null的看法。这就是我认为你对如何解决这个问题的看法。除了使用RelativePanel有一个奇怪的Image行为,但是我添加了一个MaxHeight,如果需要,可以用Text Control的ActualHeight Binding替换:
<RelativePanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualState x:Name="NarrowView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Text.(RelativePanel.Below)" Value="Image" />
<Setter Target="Content.(RelativePanel.Below)" Value="Text" />
<Setter Target="Text.(RelativePanel.RightOf)" Value="{x:Null}" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideView">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="860" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="Text.(RelativePanel.Below)" Value="{x:Null}" />
<Setter Target="Text.(RelativePanel.RightOf)" Value="Image" />
<Setter Target="Content.(RelativePanel.Below)" Value="Image" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Image x:Name="Image" Source="ms-appx:///Assets/StoreLogo.png" MaxWidth="200" />
<TextBlock x:Name="Text" RelativePanel.Below="Image" TextWrapping="WrapWholeWords" Text="Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum." />
<Border x:Name="Content" Background="Blue" RelativePanel.Below="Text" >
<TextBlock Text="Other Content" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</RelativePanel>
诀窍是将事情设置为{x:Null}它会发出一个奇怪的警告,但是它有效,我也会用它来更新我的代码项目文章。
我希望你能找到答案。
更新:RelativeSizes:
1.-我创建了自定义附加属性,以便能够为容器设置相对大小:
public class RelativeSize : DependencyObject
{
private static List<FrameworkElement> elements = new List<FrameworkElement>();
private static FrameworkElement Container = null;
private static bool containerready = false;
public static void SetContainer(UIElement element, FrameworkElement value)
{
element.SetValue(ContainerProperty, value);
}
public static FrameworkElement GetContainer(UIElement element)
{
return (FrameworkElement)element.GetValue(ContainerProperty);
}
public static readonly DependencyProperty ContainerProperty =
DependencyProperty.RegisterAttached("Container", typeof(FrameworkElement), typeof(RelativeSize), new PropertyMetadata(null,ContainerChanged));
private static void ContainerChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Container = (e.NewValue as FrameworkElement);
Container.SizeChanged += (sc, ec) =>
{
foreach (var element in elements)
{
var rWidth = element.GetValue(RelativeSize.WidthProperty);
if (rWidth != null)
{
element.Width = (double)rWidth * Container.ActualWidth;
}
}
};
containerready = true;
}
public static void SetWidth(UIElement element, double value)
{
element.SetValue(WidthProperty, value);
}
public static double GetWidth(UIElement element)
{
return (double)element.GetValue(WidthProperty);
}
public static readonly DependencyProperty WidthProperty =
DependencyProperty.RegisterAttached("Width", typeof(double), typeof(RelativeSize), new PropertyMetadata(0.0, WidthChanged));
private static async void WidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
while (!containerready)
await Task.Delay(60);
var fe = d as FrameworkElement;
if(fe!=null)
{
if (!elements.Contains(fe))
elements.Add(fe);
fe.Width = (double)e.NewValue * Container.ActualWidth;
}
}
}
2.-您可以设置:
xmlns:p="using:Controls.Views.Properties"
...
<Image x:Name="Image" p:RelativeSize.Container="{Binding ElementName=Root}" p:RelativeSize.Width="0.4" Source="ms-appx:///Assets/StoreLogo.png" />
<TextBlock x:Name="Text" RelativePanel.Below="Image" p:RelativeSize.Width="0.6" HorizontalAlignment="Left" TextWrapping="WrapWholeWords" Text="Lorem ipsum ..." />
UPDATE2 :自定义附加属性
XAML:
<VisualStateGroup x:Name="VisualStateGroup" CurrentStateChanged="VisualStateGroup_CurrentStateChanged">
代码:
private void VisualStateGroup_CurrentStateChanged(object sender, VisualStateChangedEventArgs e)
{
foreach (var sbase in e.NewState.Setters)
{
var setter = sbase as Setter;
var spath = setter.Target.Path.Path;
var element = setter.Target.Target as FrameworkElement;
if (spath.Contains(nameof(RelativeSize)))
{
string property = spath.Split('.').Last().TrimEnd(')');
var prop = typeof(RelativeSize).GetMethod($"Set{property}");
prop.Invoke(null, new object[] { element, setter.Value });
}
}
}
这是此自定义附加属性的解决方案,您可以使用更多自定义附加属性,使用命名空间中的反射并获取所有内容并按名称查找,但这样就足够了。