xaml - UWP 应用程序的 XAML 中具有RelativePanel 的 UI 元素的相对宽度

标签 xaml windows-store-apps windows-10 uwp

我想实现类似的事情

|图像(40% 宽度)|文本(60% 宽度)|

适应小屏幕,例如

|图像 (100%)|
|文字(100%|

我使用 AdaptiveTrigger 和网格得到了以下解决方案。

<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 应用提供的新 Realtive Panel 是否有类似的解决方案?

最佳答案

让我们应用一下我对 x:Null 的想法。我认为这就是您关于如何解决这个问题的意思。除此之外,使用RelativePanel 的图像有一个奇怪的行为,但我添加了一个MaxHeight,如果需要,可以将其替换为文本控件的ActualHeight 绑定(bind):

<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} 它会发出奇怪的警告,但它有效,我还将用它更新我的代码项目文章。

我希望这是您正在寻找的答案。

更新:相对大小:

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 });
        }
    }
}

这是此自定义附加属性的解决方案,您可以适应更多自定义附加属性,在命名空间中使用反射并获取所有内容并按名称查找,但这就足够了。

关于xaml - UWP 应用程序的 XAML 中具有RelativePanel 的 UI 元素的相对宽度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31852833/

相关文章:

xaml - 如何在Windows Store App中裁剪带有圆角的内容

c# - 在 WPF 中的页面之间导航?

c# - 设置用户控件可见性

c# - 如何将 WPF 用户控件的宽度拉伸(stretch)到其窗口?

c# - 如何让消息对话框居中

c# - UWP (Windows 10) 应用程序提交失败

Android 虚拟设备未运行

azure - Windows 10 驱动程序签名自动化

c# - SvgViewbox 在鼠标悬停时不显示工具提示

android - 无法启动。系统错误 : Calling js method onCreate failed