简体   繁体   English

为什么 UserControl 文本块在设计模式下会振动

[英]Why does UserControl textblock vibrates in design mode

When I add my usercontrol to a window, why does the text vibrates in design mode?.当我将用户控件添加到窗口时,为什么文本在设计模式下振动?。
问题视频

<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:隐藏代码: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 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();
        }
    }

}

Interesting case indeed, and the reason is layout rounding.确实很有趣,原因是布局四舍五入。 It seems that wpf designer by default sets UseLayoutRounding to true for the window you view in it.对于您在其中查看的窗口,wpf 设计器似乎默认将 UseLayoutRounding 设置为 true 。 However, in runtime UseLayoutRounding is false for window.但是,在运行时 UseLayoutRounding 对于窗口是假的。 What layout rounding means is things like width\\height\\margins are rounded to whole pixel during layout measurment.布局四舍五入的意思是在布局测量期间将宽度\\高度\\边距四舍五入到整个像素。 In your CenterConverter you calculate margin of textblock based on it's own height and width.在您的 CenterConverter 中,您根据它自己的高度和宽度计算文本块的边距。 But changing margin causes width change, and that in turn causes margin change.但是改变边距会导致宽度改变,进而导致边距改变。 Because of layout rounding this process never ends.由于布局四舍五入,这个过程永远不会结束。

You can verify that by setting UseLayoutRounding = false explicitly (designer will stop vibrating) or setting to true explicitly (will vibrate in runtime).您可以通过显式设置 UseLayoutRounding = false (设计器将停止振动)或显式设置为 true (将在运行时振动)来验证这一点。 In general you need to fix CenterConverter to take that into account.通常,您需要修复 CenterConverter 以将其考虑在内。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM