2016-04-01 8 views
2

Wenn ich meine Benutzersteuerung zu einem Fenster hinzufüge, warum vibriert der Text im Entwurfsmodus ?.
Video of issueWarum vibriert der UserControl-Textblock im Entwurfsmodus?

<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

Wie vibriert es? Was geschieht? – dkozl

+1

Wohnst du in einem seismisch aktiven Gebiet? –

+0

Es vibriert von links nach rechts. Ich habe ein Gif/Video, aber es ist ein bisschen zu groß zum Hochladen. Ich denke, es ist wegen der Zentrierung –

Antwort

1

Interessanter Fall in der Tat, und der Grund ist das Layout Rundung. Es scheint, dass WPF-Designer standardmäßig UseLayoutRounding für das Fenster, das darin angezeigt wird, auf true setzt. In der Laufzeit ist UseLayoutRounding jedoch false für window. Welche Layout-Rundung bedeutet, dass Dinge wie Breite \ Höhe \ Ränder während der Layout-Messung auf das ganze Pixel gerundet werden. In Ihrem CenterConverter berechnen Sie den Rand des Textblocks basierend auf seiner eigenen Höhe und Breite. Der sich ändernde Rand verursacht jedoch eine Breitenänderung, was wiederum eine Randänderung verursacht. Aufgrund der Rundung des Layouts endet dieser Prozess nie.

Sie können dies überprüfen, indem Sie explizit UseLayoutRounding = false setzen (der Designer hört auf zu vibrieren) oder explizit auf true setzen (wird in der Laufzeit vibrieren). Im Allgemeinen müssen Sie CenterConverter reparieren, um dies zu berücksichtigen.

+0

Verdammt, +1, wenn nicht nur für die Rundung Erklärung enthalten, anstatt nur es zu reparieren ... und in diesem Sinne würde ich wetten, dass der Konverter nicht notwendig ist, um das Layout zu erreichen, die Sie ' danach. Habt ein schönes Wochenende –

Verwandte Themen