سؤال

عند إنشاء UserControl في WPF, أجد أنه من المناسب أن تعطيه بعض التعسفي الطول والعرض القيم بحيث لا يمكن عرض التغييرات في مصمم Visual Studio.عند تشغيل التحكم ، ولكن أريد الطول والعرض أن تكون غير محددة ، بحيث التحكم سوف تملأ ما حاوية ووضعه في.كيف يمكنني تحقيق هذا نفس الوظائف دون الحاجة إلى إزالة الطول والعرض القيم قبل بناء بلدي السيطرة ؟ (أو بدون استخدام DockPanel في الحاوية الأصل.)

التعليمة البرمجية التالية يوضح المشكلة:

<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>

التعريف التالي UserControl1 يعرض معقول في وقت التصميم ولكن يعرض كما حجم ثابت في وقت التشغيل:

<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>

التعريف التالي UserControl1 كما يعرض نقطة في وقت التصميم ولكن يوسع لملء الوالدين Window1 في وقت التشغيل:

<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>
هل كانت مفيدة؟

المحلول

في Visual Studio إضافة العرض والارتفاع السمة الخاصة بك UserControl XAML ، ولكن في التعليمات البرمجية-خلف إدراج هذا

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

هذا التحقق لمعرفة ما إذا كان عنصر التحكم يعمل في تصميم نمط.إن لم يكن (أيوقت التشغيل) فإنه سيتم تعيين العرض والارتفاع إلى نان (وليس العدد) الذي هو قيمة قمت بتعيين أنه إلى إذا كنت إزالة سمات العرض والارتفاع في XAML.

حتى في وقت التصميم سيكون لديك مسبقا العرض والارتفاع (بما في ذلك إذا وضعت للمستخدم التحكم في شكل) و في وقت التشغيل سوف قفص الاتهام اعتمادا على الحاوية الأصل.

على أمل أن يساعد.

نصائح أخرى

للحصول على مزيج معروفة خدعة هو إضافة هذه الصفات إلى usercontrol أو النافذة:

 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"

وهذا وضع تصميم الطول و العرض 500 و 600 على التوالي.ولكن هذا سوف تعمل فقط على مزيج مصمم.ليس مصمم Visual Studio.

بقدر مصمم Visual Studio الأسلوب الخاص بك هو كل ما يعمل.والذي هو السبب في أنني لا استخدم مصمم Visual Studio.;)

هنا هي قائمة من وقت التصميم الصفات في سيلفرلايت مصمم.هم نفس مصمم WPF.

وهو يسرد جميع d: القيم المتاحة في مصمم مثل d:DesignHeight, d:DesignWidth, d:IsDesignTimeCreatable, d:CreateList والعديد من الآخرين.

أنا أفعل هذا طوال الوقت.ببساطة تعيين قيم العرض والارتفاع إلى "تلقائي" حيث يمكنك إنشاء عنصر التحكم الخاص بك ، وهذا تجاوز وقت التصميم القيم التي UserControl.

أي: <loc:UserControl1 Width="auto" Height="auto" />

وثمة خيار آخر هو مزيج من MinWidth و MinHeight إلى الحجم الذي يسمح تصميم-وقت العمل ، في حين أن العرض والارتفاع تبقى "السيارات".ومن الواضح أن هذا يعمل فقط إذا كنت لا تحتاج UserControl إلى حجم أصغر من مين القيم في وقت التشغيل.

كنت أبحث عن مماثلة حل مثل تلك المستخدمة في مزيج مع ذكر أنا خلقت بسيطة سلوك الطبقة مع اثنين من تعلق خصائص العرض و الارتفاع التي يتم تطبيقها فقط في DesinTime

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

}

ثم في UserControl يمكنك فقط تعيين هذه الخصائص في 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>

استخدام MinWidth و MinHeight على السيطرة.بهذه الطريقة, سوف نرى ذلك في مصمم و في وقت التشغيل سيكون حجم بالطريقة التي تريدها.

أفعل ذلك مشابهة ، ولكن الحل يؤكد أن إذا قمت بإضافة عنصر التحكم الخاص بك إلى حاوية في وضع التصميم ، سوف تظهر بشكل معقول.

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

ماذا تعتقد ؟

شكرا الأصلي المجيب على الأسئلة لهذا الحل!بالنسبة لأولئك الذين يهتمون ، ومن هنا في VB:

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

وقد اقترح البعض استخدام LicenseManager.UsageMode الملكية التي لم أرها من قبل ولكن يجب استخدام التعليمات البرمجية التالية.

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

esskar,

أنا فقط أريد أن أضيف أنه يجب عليك دائما عموما استدعاء الأسلوب من القاعدة عندما تجاوز "على" الأسلوب.

protected override void OnVisualParentChanged(DependencyObject oldParent)
{
    base.OnVisualParentChanged(oldParent);

    ...
}

رائعة الحل بالمناسبة, أنا باستخدام بنفسي الآن أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top