x:Null についての私の考えを適用してみましょう。それが、これを解決する方法についてあなたが意味していることだと思います。これとは別に、RelativePanel を使用した Image の奇妙な動作がありますが、必要に応じてテキスト コントロールの ActualHeight Binding に置き換えることができる MaxHeight を追加しました。
<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 });
}
}
}
これは、このカスタム添付プロパティのソリューションであり、名前空間でリフレクションを使用してすべてを取得し、名前で検索して、より多くのカスタム添付プロパティに適応できますが、これで十分です。