找到工作区测量值并在代码中设置一些属性以便它可以绑定(bind)到 xaml 中控件的边距或高度/宽度属性是否是一个好习惯?
我这样做是为了让我的窗口根据可用的工作区调整大小。
const int w = SystemParameters.WorkArea.Width;
const int h = SystemParameters.WorkArea.Height;
public Thickness OuterGridMargin { get; }
MainViewModel()
{
OuterGridMargin = new Thickness(w/5,h/6,w/5,h/4);
}
xaml:
<Grid Margin="{Binding OuterGridMargin}" />
我对一些外部容器执行此操作,以便布局不会在较低分辨率下困惑。目前,我在 20"分辨率下使用 1600x900 分辨率(96 dpi)工作。我的应用程序类似于小工具,没有常规窗口。
我想知道是否有一些替代方法。
搜索 [wpf] 分辨率] 1给出了很多解决类似问题的问题,但我仍然卡住了,无法得出结论如何实现良好的分辨率独立布局。
最佳答案
在 WPF 中有两种处理分辨率的方法。
一个选择是设计最小分辨率,并确保所有内容都正确停靠,以便元素随着窗口分辨率变大而变大。这就是很多人在 WinForms 中所做的事情,并且在 WPF 中仍然工作得很好。您可能已经对如何通过设置 HorizontalAlignment、VerticalAlignment 和边距来处理这个问题有了一些概念。
在 WinForms 中几乎不可能在 WPF 中做的更新、更时髦的事情是让您的应用程序实际上只是放大,这样您的控件就可以像窗口一样变大。为此,您将在 Window 中的某个根元素上应用 ScaleTransform,让 WPF 处理其余部分。这真的很酷。
为了展示它的样子,下面是启动应用程序时窗口的样子,将其变小,然后再变大:http://i.stack.imgur.com/QeoVK.png
这是我制作的小型示例应用程序的代码隐藏:
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
#region ScaleValue Depdency Property
public static readonly DependencyProperty ScaleValueProperty = DependencyProperty.Register("ScaleValue", typeof(double), typeof(MainWindow), new UIPropertyMetadata(1.0, new PropertyChangedCallback(OnScaleValueChanged), new CoerceValueCallback(OnCoerceScaleValue)));
private static object OnCoerceScaleValue(DependencyObject o, object value)
{
MainWindow mainWindow = o as MainWindow;
if (mainWindow != null)
return mainWindow.OnCoerceScaleValue((double)value);
else return value;
}
private static void OnScaleValueChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
MainWindow mainWindow = o as MainWindow;
if (mainWindow != null)
mainWindow.OnScaleValueChanged((double)e.OldValue, (double)e.NewValue);
}
protected virtual double OnCoerceScaleValue(double value)
{
if (double.IsNaN(value))
return 1.0f;
value = Math.Max(0.1, value);
return value;
}
protected virtual void OnScaleValueChanged(double oldValue, double newValue) { }
public double ScaleValue
{
get => (double)GetValue(ScaleValueProperty);
set => SetValue(ScaleValueProperty, value);
}
#endregion
private void MainGrid_SizeChanged(object sender, EventArgs e) => CalculateScale();
private void CalculateScale()
{
double yScale = ActualHeight / 250f;
double xScale = ActualWidth / 200f;
double value = Math.Min(xScale, yScale);
ScaleValue = (double)OnCoerceScaleValue(myMainWindow, value);
}
}
XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Name="myMainWindow"
Width="200" Height="250">
<Grid Name="MainGrid" SizeChanged="MainGrid_SizeChanged">
<Grid.LayoutTransform>
<ScaleTransform x:Name="ApplicationScaleTransform"
CenterX="0"
CenterY="0"
ScaleX="{Binding ElementName=myMainWindow, Path=ScaleValue}"
ScaleY="{Binding ElementName=myMainWindow, Path=ScaleValue}" />
</Grid.LayoutTransform>
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Height="150">
<TextBlock FontSize="20" Text="Hello World" Margin="5" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Button Content="Button" VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
</Grid>
</Grid>
关于c# - 开发与分辨率无关的应用程序的技巧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3193339/