2008-09-16 5 views
49

Wenn ich ein UserControl in WPF erstelle, finde ich es bequem, es einige beliebige Höhe und Breite Werte zu geben, so dass ich meine Änderungen im Visual Studio Designer sehen kann. Wenn ich die Kontrolle laufen, möchte ich jedoch die Höhe und Breite nicht definiert sein, so dass die Steuerung erweitern zu füllen, was Behälter ich es an seinem Platz. Wie kann ich diese gleiche Funktionalität acheive, ohne die Werte Höhe und Breite zu entfernen, bevor meine Kontrolle aufbauen? (. Oder ohne DockPanel in den übergeordneten Container mit)WPF UserControl Design Zeit Größe

Der folgende Code demonstriert das Problem:

<Window x:Class="ExampleApplication3.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:loc="clr-namespace:ExampleApplication3" 
    Title="Example" Height="600" Width="600"> 
    <Grid Background="LightGray"> 
     <loc:UserControl1 /> 
    </Grid> 
</Window> 

Die folgende Definition von UserControl1 Displays angemessen zur Entwurfszeit wird jedoch als eine feste Größe zur Laufzeit:

<UserControl x:Class="ExampleApplication3.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid Background="LightCyan" /> 
</UserControl> 

die folgende Definition von UserControl1 Displays als Punkt zur Design-Zeit, sondern erweitert die Eltern Window1 zur Laufzeit zu füllen:

<UserControl x:Class="ExampleApplication3.UserControl1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid Background="LightCyan" /> 
</UserControl> 

Antwort

38

in Visual Studio die Breite und Höhe Attribut zu Ihrem Usercontrol XAML hinzuzufügen, aber in der Code-Behind diesen Diesen prüft

public UserControl1() 
{ 
    InitializeComponent(); 
    if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) 
    { 
     this.Width = double.NaN; ; 
     this.Height = double.NaN; ; 
    } 
} 

einfügen, um zu sehen, ob die Steuerung im Designer-Modus läuft. Wenn nicht (d. H. Laufzeit) wird die Breite und Höhe auf NaN (keine Zahl) gesetzt, was der Wert ist, auf den Sie sie einstellen, wenn Sie die Attribute Breite und Höhe in XAML entfernen.

So zur Entwurfszeit haben Sie die vorgegebene Breite und Höhe (einschließlich, wenn Sie die Benutzersteuerung in einer Form gebracht) und zur Laufzeit wird es andocken an seinem übergeordneten Container abhängig.

Hoffe, dass hilft.

+0

Kann dies in umgekehrter Weise getan werden? Das heißt, kann ich die Benutzersteuerung XAML Höhe/Breite undefiniert lassen und dann eine Höhe und width im Konstruktor NUR wenn LicenseManager.UsageMode == LicenseUsageMode.Designtime? –

+0

@Patrick: Scheinbar nicht. Das heißt, es funktioniert nicht für mich. – Thomas

+0

Leider enthält LicenseUsageMode keine Designtime. – jonatr

78

Für Blend, ein wenig bekannter Trick ist es, diese Attribute zu Ihrem Usercontrol oder Fenster hinzuzufügen:

xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
     d:DesignHeight="500" d:DesignWidth="600" 

Dies wird die Bauhöhe und Breite auf 500 und 600 jeweils eingestellt. Dies funktioniert jedoch nur für den Blend Designer. Nicht der Visual Studio Designer.

Soweit der Visual Studio Designer Ihre Technik ist alles, was funktioniert. Aus diesem Grund verwende ich den Visual Studio Designer nicht. ;)

+0

Leider führt dies dazu, dass der Visual Studio Designer den Inhalt überhaupt nicht rendert :( –

+0

oh ... ich benutze es nicht, ich werde die Antwort ändern –

+34

Dieser Trick wird mit VS2010 funktionieren. – wekempf

6

Ich mache das die ganze Zeit. Legen Sie einfach die Werte für width und height auf "auto" fest, wo Sie Ihr Steuerelement instanziieren, und dadurch werden die Entwurfszeitwerte für dieses UserControl überschrieben.

dh: <loc:UserControl1 Width="auto" Height="auto" />

Eine weitere Option ist eine Kombination aus MinWidth und MinHeight auf eine Größe einzustellen, die Design-Zeitarbeit ermöglicht, während Breite und Höhe bleiben „auto“. Dies funktioniert natürlich nur, wenn Sie das UserControl nicht benötigen, um zur Laufzeit kleiner als die min-Werte zu sein.

0

Ich mache es ähnlich, aber meine Lösung stellt sicher, dass, wenn Sie Ihre Steuerung an einen Container im Design-Modus hinzufügen, es vernünftig erscheinen.

protected override void OnVisualParentChanged(DependencyObject oldParent) 
{ 
    if (this.Parent != null) 
    { 
     this.Width = double.NaN; 
     this.Height = double.NaN; 
    } 
} 

was denken Sie?

+0

Wenn Sie Remwerter überschreiben zu Fallbasis. base.OnVisualParentChanged (oldParent); –

0

Dank der ursprünglichen Beantworter für diese Lösung! Für diejenigen, die interessiert sind, hier ist es in VB:

If LicenseManager.UsageMode <> LicenseUsageMode.Designtime Then 
    Me.Width = Double.NaN 
    Me.Height = Double.NaN 
End If 
0

Einige der LicenseManager.UsageMode Eigenschaft vorgeschlagen haben, mit dem ich noch nie gesehen habe, aber ich habe den folgenden Code verwendet.

if(!DesignerProperties.GetIsInDesignMode(this)) 
{ 
    this.Width = double.NaN; 
    this.Height = double.NaN; 
} 

esskar,

Ich möchte nur hinzufügen, dass Sie in der Regel immer die Methode der Basis anrufen sollte, wenn ein „On“ Methode überschrieben.

Große Workaround übrigens, ich benutze es jetzt auch ich.

+0

Beachten Sie, dass diese Lösung sowie die anderen bisher angebotenen Lösungen das Problem der Anzeige dieser Steuerelementeigenschaft nicht lösen, wenn sie in einem anderen Steuerelement verwendet wird und diese Kontrolle im Designer angezeigt wird. Hoffentlich werden die neuen DesignHeight- und DesignWidth-Eigenschaften das lösen, das ist Visual Studio 2010. – jpierson

2

Ich war für ähnliche Lösung wie die in Mischung verwendet suchen und mit Ihrem erwähnt ich mit zwei aufgesetzten Eigenschaften Breite & Höhe einfache Verhaltensklasse erstellt, die nur in DesinTime angewandt werden

 
public static class DesignBehavior 
{ 
    private static readonly Type OwnerType = typeof (DesignBehavior); 

    #region Width 

    public static readonly DependencyProperty WidthProperty = 
     DependencyProperty.RegisterAttached(
      "Width", 
      typeof (double), 
      OwnerType, 
      new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(WidthChangedCallback))); 

    public static double GetWidth(DependencyObject depObj) 
    { 
     return (double)depObj.GetValue(WidthProperty); 
    } 

    public static void SetWidth(DependencyObject depObj, double value) 
    { 
     depObj.SetValue(WidthProperty, value); 
    } 

    private static void WidthChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     if (DesignerProperties.GetIsInDesignMode(depObj)) { 
      depObj.SetValue(FrameworkElement.WidthProperty, e.NewValue); 
     } 
    } 

    #endregion 

    #region Height 

    public static readonly DependencyProperty HeightProperty = 
     DependencyProperty.RegisterAttached(
      "Height", 
      typeof (double), 
      OwnerType, 
      new FrameworkPropertyMetadata(double.NaN, new PropertyChangedCallback(HeightChangedCallback))); 

    public static double GetHeight(DependencyObject depObj) 
    { 
     return (double)depObj.GetValue(HeightProperty); 
    } 

    public static void SetHeight(DependencyObject depObj, double value) 
    { 
     depObj.SetValue(HeightProperty, value); 
    } 


    private static void HeightChangedCallback(DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     if (DesignerProperties.GetIsInDesignMode(depObj)) { 
      depObj.SetValue(FrameworkElement.HeightProperty, e.NewValue); 
     } 
    } 

    #endregion 

} 

Dann sind Sie in Ihrem Usercontrol Setzen Sie diese Eigenschaften nur in Xaml

 
<UserControl x:Class="ExtendedDataGrid.Views.PersonOverviewView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:tool="http://schemas.microsoft.com/wpf/2008/toolkit" 
    xmlns:b="clr-namespace:ExtendedDataGrid.Behaviors" 
    b:DesignBehavior.Width="600" b:DesignBehavior.Height="200"> 
    <Grid> 
     ... 
    </Grid> 
</UserControl> 
1

Verwenden Sie MinWidth und MinHeight auf dem Steuerelement. Auf diese Weise sehen Sie es im Designer und zur Laufzeit wird es die Größe, die Sie wollen.