MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как правильно воспользоваться StackPanel?"
Answer 1263213
Но мне не нравится то, что в разметке парные-элементы никак не группируются между собой...
Сгруппировать то легко, запихнуть каждую пару в свой Grid, да и все тут. Поведение в отношении размера стобцов у одного Grid и последовательности однострочных Grid идентично. Но, глядя на вашу разметку, смущает скорее дублирование строк и элементов. Если у вас в разметке куча однотипных пар Label + (что-то), которые ходят вместе и образуют строку таблицы, должны ли они быть отдельными элементами? По моему, это отличный повод для создания своего элемента управления.
Раз нам нужно поведение Grid в плане изменения размеров столбцов, этот элемент управления можно сделать производным от Grid:
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; namespace WpfTest { public class ControlPair : Grid { UIElement first; UIElement second; public UIElement First { get { return this.first; } set { this.first = value; UpdateChildren(); } } public UIElement Second { get{ return this.second; } set { this.second = value; UpdateChildren(); } } void UpdateChildren() { this.Children.Clear(); if (this.first != null) { this.Children.Add(this.first); Grid.SetColumn(this.first, 0); } if (this.second != null) { this.Children.Add(this.second); Grid.SetColumn(this.second, 1); } } public ControlPair() : base() { this.ColumnDefinitions.Clear(); this.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0.5, GridUnitType.Star) }); this.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(0.5, GridUnitType.Star) }); this.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto }); } } }
Здесь у элемента управления есть два свойства, First и Second, которым можно присвоить любой элемент управления. Элементы помещаются в ячейки Grid, для которых задан определенный процент доступного пространства. Тогда мы можем в разметке делать так:
<local:ControlPair> <local:ControlPair.First> <Label Content="Тип БД"></Label> </local:ControlPair.First> <local:ControlPair.Second> <ComboBox/> </local:ControlPair.Second> </local:ControlPair>
И элементы сгруппированы, и не нужна куча RowDefinition.
Более развернутый пример, как это можно применить на практике:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfTest" x:Class="WpfTest.MainWindow" Height="250" Width="400" > <Grid> <StackPanel> <local:ControlPair HorizontalAlignment="Stretch"> <local:ControlPair.First> <Label Content="Тип БД"></Label> </local:ControlPair.First> <local:ControlPair.Second> <ComboBox ItemsSource="{Binding Path=DatabaseTypeValues}" Text="{Binding Path=DatabaseTypeSelected,Mode=TwoWay}"/> </local:ControlPair.Second> </local:ControlPair> <local:ControlPair HorizontalAlignment="Stretch"> <local:ControlPair.First> <Label Content="База данных"></Label> </local:ControlPair.First> <local:ControlPair.Second> <TextBox Text="{Binding Path=Database,Mode=TwoWay}"/> </local:ControlPair.Second> </local:ControlPair> <Button x:Name="myButton" Content="Save" HorizontalAlignment="Left" Height="40" Margin="10,10,10,10" VerticalAlignment="Top" Width="100" Click="Button_Click" /> </StackPanel> </Grid> </Window>
using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; namespace WpfTest { public partial class MainWindow : Window { Options optionsData; public MainWindow() { InitializeComponent(); optionsData = new Options(); optionsData.DatabaseTypeValues = new string[] { "SQL Server", "Access" }; this.DataContext = optionsData; } private void Button_Click(object sender, RoutedEventArgs e) { //show selected options MessageBox.Show("Selected " + "\nDatabaseType: " + optionsData.DatabaseTypeSelected + "\nDatabase: " + optionsData.Database ); } } public class Options { public string[] DatabaseTypeValues { get; set; } public string DatabaseTypeSelected { get; set; } public string Database { get; set; } } }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.