كيفية الحصول على أطفال StackPanel لملء أقصى مساحة إلى أسفل؟
-
05-09-2019 - |
سؤال
أنا ببساطة أريد النص المتدفقة على اليسار، وصندوق مساعدة على اليمين.
يجب أن يمتد مربع المساعدة طوال الطريق إلى الأسفل.
إذا قمت بإخراج StackPanel الخارجي تحت أنه يعمل بشكل رائع.
ولكن لأسباب تخطيط (أنا أدرج USERERCONTROLS ديناميكيا) أحتاج إلى التغليف StackPanel.
كيف يمكنني الحصول على مربع المجموعة لتمتد لأسفل إلى أسفل StackPanel، كما ترون لقد حاولت:
- Verticalignment = "تمتد"
- VerticalContenthigigignment = "تمتد"
- الارتفاع = "السيارات"
XAML:
<Window x:Class="TestDynamic033.Test3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test3" Height="300" Width="600">
<StackPanel
VerticalAlignment="Stretch"
Height="Auto">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
Background="Beige"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap" />
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</StackPanel>
</Window>
إجابه:
شكرا جزيلا، باستخدام dockpanel بدلا من stackpanel تطهيرها. بشكل عام، أجد نفسي أستخدم DockPanel أكثر فأكثر الآن بالنسبة لتخطيط WPF، إليك XAML الثابتة:
<Window x:Class="TestDynamic033.Test3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test3" Height="300" Width="600" MinWidth="500" MinHeight="200">
<DockPanel
VerticalAlignment="Stretch"
Height="Auto">
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
MinWidth="400"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<Border CornerRadius="3" Background="Beige">
<TextBlock Text="This is the help that is available on the news screen." TextWrapping="Wrap"
Padding="5"/>
</Border>
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10" Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around." TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</DockPanel>
</Window>
المحلول
يبدو وكأنك تريد StackPanel
حيث يستخدم العنصر النهائي كل المساحة المتبقية. ولكن لماذا لا تستخدم DockPanel
ب تزيين العناصر الأخرى في DockPanel
مع DockPanel.Dock="Top"
, ، ثم التحكم في مساعدتكم يمكن أن تملأ المساحة المتبقية.
XAML:
<DockPanel Width="200" Height="200" Background="PowderBlue">
<TextBlock DockPanel.Dock="Top">Something</TextBlock>
<TextBlock DockPanel.Dock="Top">Something else</TextBlock>
<DockPanel
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Height="Auto"
Margin="10">
<GroupBox
DockPanel.Dock="Right"
Header="Help"
Width="100"
Background="Beige"
VerticalAlignment="Stretch"
VerticalContentAlignment="Stretch"
Height="Auto">
<TextBlock Text="This is the help that is available on the news screen."
TextWrapping="Wrap" />
</GroupBox>
<StackPanel DockPanel.Dock="Left" Margin="10"
Width="Auto" HorizontalAlignment="Stretch">
<TextBlock Text="Here is the news that should wrap around."
TextWrapping="Wrap"/>
</StackPanel>
</DockPanel>
</DockPanel>
إذا كنت على منصة دون DockPanel
متاح (مثل WindowsStore)، يمكنك إنشاء نفس التأثير مع شبكة. هنا المثال أعلاه أنجز استخدام الشبكات بدلا من ذلك:
<Grid Width="200" Height="200" Background="PowderBlue">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<TextBlock>Something</TextBlock>
<TextBlock>Something else</TextBlock>
</StackPanel>
<Grid Height="Auto" Grid.Row="1" Margin="10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<GroupBox
Width="100"
Height="Auto"
Grid.Column="1"
Background="Beige"
Header="Help">
<TextBlock Text="This is the help that is available on the news screen."
TextWrapping="Wrap"/>
</GroupBox>
<StackPanel Width="Auto" Margin="10" DockPanel.Dock="Left">
<TextBlock Text="Here is the news that should wrap around."
TextWrapping="Wrap"/>
</StackPanel>
</Grid>
</Grid>
نصائح أخرى
السبب في أن هذا يحدث هو أن لوحة المكدس يقيس كل عنصر طفل مع اللانهاية الإيجابية كقيد للمحور الذي يكتب عناصره على طول. يجب أن يؤدي ضوابط الأطفال إلى إرجاع مدى الكبار أن تكون (إنفينيتي إيجابية ليست عودة صالحة من exprayerride. في أي محور) حتى يعودون أصغر حجم حيث كل شيء سوف يصلح. ليس لديهم طريقة لمعرفة مقدار المساحة التي يتعين عليهم ملءها حقا.
إذا لم يكن هناك حاجة نظرك إلى الحصول على ميزة التمرير والإجابة أعلاه لا تناسب احتياجاتك، أود أن أقترح تنفيذ اللوحة الخاصة بك. ربما يمكنك أن تستمد مباشرة من StackPanel ثم كل ما تحتاجه للقيام به هو تغيير ArrangeOverride. الطريقة بحيث تقسم المساحة المتبقية بين عناصرها للأطفال (مما يمنحها كل كمية من المساحة الإضافية). يجب أن تجعل العناصر غرامة إذا تم إعطاء مساحة أكبر مما أرادوا، ولكن إذا أعطيتهم أقل ستبدأ في رؤية مواطن الخلل.
إذا كنت ترغب في أن تكون قادرا على التمرير كل شيء كله، فأنا أخشى أن تكون الأمور أكثر صعوبة للغاية، لأن ScrollViewer يمنحك كمية لا حصر لها من المساحة للعمل الذي سيضعك في نفس الموقف الذي كانت عليه عناصر الأطفال في الأصل. في هذه الحالة، قد ترغب في إنشاء خاصية جديدة على اللوحة الجديدة التي تتيح لك تحديد حجم Viewport، يجب أن تكون قادرا على ربط هذا بحجم التبديل. من الناحية المثالية سوف تنفذ iscrollinfo., ، ولكن هذا يبدأ في التعقيد إذا كنت ستنفذ كل ذلك بشكل صحيح.
طريقة بديلة هي استخدام شبكة مع عمود واحد و ن الصفوف. اضبط كل الصفوف المرتفعة Auto
, ، وارتفاع ارتفاع الصف السفلي إلى 1*
.
أفضل هذه الطريقة لأنني عثرت على شبكات لديها أداء تخطيط أفضل من DockPanels و Stackpanels والاجطات. ولكن ما لم تكن تستخدمها في فندقة (حيث يتم تنفيذ التخطيط لعدد كبير من العناصر)، فربما لن تلاحظ أبدا.
يمكنك استخدام نسخة تعديل من stackpanel:
<st:StackPanel Orientation="Horizontal" MarginBetweenChildren="10" Margin="10">
<Button Content="Info" HorizontalAlignment="Left" st:StackPanel.Fill="Fill"/>
<Button Content="Cancel"/>
<Button Content="Save"/>
</st:StackPanel>
الزر الأول سيكون ملء.
يمكنك تثبيته عبر Nuget:
Install-Package SpicyTaco.AutoGrid
وأوصي أيضا بإلقاء نظرة على WPF-Autogrid.. وبعد من المفيد للغاية بالنماذج في WPF بدلا من DockPanel و StackPanel وشبكة وحل المشكلة مع تمديد سهل للغاية وأمان. مجرد إلقاء نظرة على README على جيثب.
<st:AutoGrid Columns="160,*" ChildMargin="3">
<Label Content="Name:"/>
<TextBox/>
<Label Content="E-Mail:"/>
<TextBox/>
<Label Content="Comment:"/>
<TextBox/>
</st:AutoGrid>
زوجين من الأشياء التي يمكنك القيام بها:
1: تعيين Orientation
ل رأسي:
<StackPanel Orientation="Vertical"></StackPanel>
تعيين
Height
التابعStackPanel
إلى نفس النافذة:
وبالطبع، يمكنك الجمع بين هؤلاء الخصائص:
<StackPanel Orientation="Vertical" Height="600"></StackPanel>
لا تحتاج إلى القيام بمجموعة كاملة من العمل الإضافي مع تثبيت Nugets و Whatnot ....
تعديل
يمكنك أيضا وضع StackPanel داخل ScrollViewer. سيسمح لك ذلك بالتحكم في ارتفاع مجموعة المجموعة دون التضحية بوضوح المحتوى.
<GroupBox>
<ScrollViewer>
<StackPanel Orientation="Vertical>
<!-- Place Children Objects here-->
<StackPanel>
<ScrollViewer>
<GroupBox>