2015-10-14 34 views
0

优化在屏幕上显示图像的方式我需要设计两个视图,检测屏幕比例(4:3或16:9及以上)并在它们之间切换。基于屏幕分辨率的wpf多视图

在4:3的屏幕上的内容应当竖向显示(按行)这样的:


toolbars 25% 
---------------- 
image 
---------------- 
toolbars 25% 
---------------- 

在16:9的显示器水平(由列)这样的:

t | i | t 
o | m | o 
o | a | o 
l | g | l 
b | e | b 
a |  | a 
r |  | r 
s |  | s 
    |  | 

屏幕比例检测完成。 我试图与视觉状态管理器和datatemplate切换视图,但我不能结束这个谷歌搜索适当的'标准'的解决方案。

任何指导方针?

+0

这只是一个想法,但你可以尝试使用连接在网格上的属性,并有你自己的代码操纵网格的子节点。 (使他们根据比例改变他们的Grid.Row/Column值,值得一试,这就是我想要做的事情,另一种选择是模板选择器 – Dbl

+0

我在尝试你的第一个建议之前,提供一个模板选择器技术的小例子?谢谢 – sam

回答

0

这应该做的工作,以及我想。有一些编码留给你虽然

用法:

<Window x:Class="ResponsiveWpfLayout.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:responsiveWpfLayout="clr-namespace:ResponsiveWpfLayout" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
     <responsiveWpfLayout:ResponsiveLayout> 
      <responsiveWpfLayout:ResponsiveLayout.DefaultTemplate> 
       <ControlTemplate> 
        <Border Background="Red"> 
         <TextBlock>Layout A</TextBlock> 
        </Border> 
       </ControlTemplate> 
      </responsiveWpfLayout:ResponsiveLayout.DefaultTemplate> 
      <responsiveWpfLayout:ResponsiveLayout.AlternativeTemplate> 
       <ControlTemplate> 
        <Border Background="Green"> 
         <TextBlock>Layout B</TextBlock> 
        </Border> 
       </ControlTemplate> 
      </responsiveWpfLayout:ResponsiveLayout.AlternativeTemplate> 
     </responsiveWpfLayout:ResponsiveLayout> 

    </Grid> 
</Window> 

ResponsiveLayout.cs

public class ResponsiveLayout : Control 
    { 
     static ResponsiveLayout() 
     { 
      DefaultStyleKeyProperty.OverrideMetadata(typeof(ResponsiveLayout), new FrameworkPropertyMetadata(typeof(ResponsiveLayout))); 
     } 

     public static readonly DependencyProperty DefaultTemplateProperty = DependencyProperty.Register(
      "DefaultTemplate", typeof (ControlTemplate), typeof (ResponsiveLayout), new PropertyMetadata(default(ControlTemplate))); 

     public ControlTemplate DefaultTemplate 
     { 
      get { return (ControlTemplate) GetValue(DefaultTemplateProperty); } 
      set { SetValue(DefaultTemplateProperty, value); } 
     } 

     public static readonly DependencyProperty AlternativeTemplateProperty = DependencyProperty.Register(
      "AlternativeTemplate", typeof (ControlTemplate), typeof (ResponsiveLayout), new PropertyMetadata(default(ControlTemplate))); 

     public ControlTemplate AlternativeTemplate 
     { 
      get { return (ControlTemplate) GetValue(AlternativeTemplateProperty); } 
      set { SetValue(AlternativeTemplateProperty, value); } 
     } 

     public static readonly DependencyProperty ActiveTemplateProperty = DependencyProperty.Register(
      "ActiveTemplate", typeof (ControlTemplate), typeof (ResponsiveLayout), new PropertyMetadata(default(ControlTemplate))); 

     public ControlTemplate ActiveTemplate 
     { 
      get { return (ControlTemplate) GetValue(ActiveTemplateProperty); } 
      set { SetValue(ActiveTemplateProperty, value); } 
     } 

     protected override Size ArrangeOverride(Size arrangeBounds) 
     { 
      if (arrangeBounds.Width > arrangeBounds.Height) 
      { 
       ActiveTemplate = DefaultTemplate; 
      } 
      else 
      { 
       ActiveTemplate = AlternativeTemplate; 
      } 

      return base.ArrangeOverride(arrangeBounds); 
     } 

     public ResponsiveLayout() 
     { 
      ActiveTemplate = DefaultTemplate; 
     } 
    } 

Generic.xaml

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:ResponsiveWpfLayout"> 


    <Style TargetType="{x:Type local:ResponsiveLayout}"> 
     <Setter Property="DefaultTemplate"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border Background="Orange"> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="AlternativeTemplate"> 
      <Setter.Value> 
       <ControlTemplate> 
        <Border Background="Blue"> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type local:ResponsiveLayout}"> 
        <Border Background="{TemplateBinding Background}" 
          BorderBrush="{TemplateBinding BorderBrush}" 
          BorderThickness="{TemplateBinding BorderThickness}"> 
         <ContentControl Template="{TemplateBinding ActiveTemplate}"></ContentControl> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</ResourceDictionary> 
+0

由于一些UI元素很昂贵(图像和视频)有没有一种方法可以引用完全相同的UI元素,而无需在两个模板中实例化一个新的? – sam

+0

我不是我想你可以在资源中声明一个控件,并且通过引用资源中的模板将它显示在两个模板中,至少这就是我想要的:) – Dbl