当我将usercontrol添加到窗口时,为什么文本会在设计模式下振动?
<UserControl x:Class="AircraftGauges.InnerGauge"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:AircraftGauges"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="200"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<UserControl.Resources>
<local:CenterConverter x:Key="CenterConverter"/>
</UserControl.Resources>
<Canvas Width="200" Height="200" Background="White">
<Path Stroke="Black" StrokeThickness="1" Data="M 40, 95 V 105 H 160 V 95 H 105 V 85 H 95 V 95 Z " Fill="Black"/>
<TextBlock Name="CenterLabel" Text="{Binding PathData}" Foreground="Black" VerticalAlignment="Center"
Canvas.Left="100" Canvas.Top="112">
<TextBlock.Margin>
<MultiBinding Converter="{StaticResource CenterConverter}">
<Binding ElementName="CenterLabel" Path="ActualWidth"/>
<Binding ElementName="CenterLabel" Path="ActualHeight"/>
</MultiBinding>
</TextBlock.Margin>
</TextBlock>
</Canvas>
</UserControl>
Code Behind:InnerGauge.xaml.cs:
namespace AircraftGauges
{
/// <summary>
/// Interaction logic for InnerGauge.xaml
/// </summary>
public partial class InnerGauge : UserControl, INotifyPropertyChanged
{
private string _path;
public event PropertyChangedEventHandler PropertyChanged;
public InnerGauge()
{
InitializeComponent();
SizeChanged += SizeChangedEventHandler;
}
private void SizeChangedEventHandler(object sender, SizeChangedEventArgs e)
{
UpdatePathData(e.NewSize.Width, e.NewSize.Height);
}
private void UpdatePathData(double w, double h)
{
var newPath = $"W {w} -- H {h}";
if (String.CompareOrdinal(_path, newPath) != 0)
{
_path = newPath;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PathData)));
}
}
public string PathData
{
get
{
return _path;
}
}
}
}
CenterConverter.cs
namespace AircraftGauges
{
public class CenterConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] == DependencyProperty.UnsetValue || values[1] == DependencyProperty.UnsetValue)
{
return DependencyProperty.UnsetValue;
}
var width = (double) values[0];
var height = (double) values[1];
return new Thickness(-width/2, -height/2, 0, 0);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
答案 0 :(得分:1)
确实有趣的案例,原因是布局四舍五入。似乎wpf设计器默认将UseLayoutRounding设置为true,用于您在其中查看的窗口。但是,在运行时,对于窗口,UseLayoutRounding为false。什么布局舍入意味着像width \ height \ margin这样的东西在布局测量期间舍入到整个像素。在CenterConverter中,您可以根据文本块的高度和宽度计算文本块的边距。但是改变保证金会导致宽度变化,从而导致利润变化。由于布局四舍五入,这个过程永远不会结束。
您可以通过显式设置UseLayoutRounding = false(设计器将停止振动)或显式设置为true(将在运行时振动)来验证。通常,您需要修复CenterConverter以将其考虑在内。