WPF 自适应布局控件
public class KDLayoutGroup : Grid { public double LabelWidth { get; set; } public double GetLabelWidth() { return LabelWidth; } public void SetLabelWidth(double value) { if (this.Parent is KDLayoutControl) { double w = (this.Parent as KDLayoutControl).GetLableWidth(); if (w < value) { (this.Parent as KDLayoutControl).SetLabelWidth(value); } for (int i = 0; i < Children.Count; i++) { SetBatchLabelWidth(Children[i], value); } } } protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { if (Children.Count == this.ColumnDefinitions.Count) return; for (int i = 0; i < Children.Count; i++) { var column = new ColumnDefinition(); //column.Width = new GridLength(0,GridUnitType.Auto); this.ColumnDefinitions.Add(column); Children[i].SetValue(Grid.ColumnProperty, i); SetBatchLabelWidthOther(Children[i]); } base.OnRenderSizeChanged(sizeInfo); } private void SetBatchLabelWidth(UIElement el, double value) { if (el is KDLayoutItem) { double width = (el as KDLayoutItem).GetLabelWidht(); if (width < value) { (el as KDLayoutItem).SetLabelWidht(value); } } else { if (el is Panel) { var cs = (el as Panel).Children; for (int i = 0; i < cs.Count; i++) { SetBatchLabelWidth(cs[i], value); } } } } private void SetBatchLabelWidthOther(UIElement el) { if (el is KDLayoutItem) { double width = (el as KDLayoutItem).GetLabelWidht(); if (width > LabelWidth) { LabelWidth = width; SetLabelWidth(width); } } else { if (el is Panel) { var cs = (el as Panel).Children; for (int i = 0; i < cs.Count; i++) { SetBatchLabelWidthOther(cs[i]); } } } } }
public class KDLayoutControl : StackPanel { public double LabelWidth { get; set; } public double GetLableWidth() { return LabelWidth; } public void SetLabelWidth(double value) { LabelWidth = value; for (int i = 0; i < Children.Count; i++) { if ((Children[i] as KDLayoutGroup).GetLabelWidth() < LabelWidth) { (Children[i] as KDLayoutGroup).SetLabelWidth(LabelWidth); } } } protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo) { for (int i = 0; i < Children.Count; i++) { if ((Children[i] as KDLayoutGroup).GetLabelWidth() > LabelWidth) { LabelWidth = (Children[i] as KDLayoutGroup).GetLabelWidth(); } } SetLabelWidth(LabelWidth); base.OnRenderSizeChanged(sizeInfo); } }
<UserControl x:Class="PHMES.UI.Base.KDLayoutItem" 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:PHMES.UI.Base" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <UserControl.Template> <ControlTemplate TargetType="local:KDLayoutItem"> <DockPanel> <Label x:Name="lbl" VerticalAlignment="Center" VerticalContentAlignment="Center" Content="{TemplateBinding Label}" /> <ContentPresenter/> </DockPanel> </ControlTemplate> </UserControl.Template> </UserControl>
public partial class KDLayoutItem : UserControl { public KDLayoutItem() { InitializeComponent(); } public object Label { get { return (object)GetValue(LabelProperty); } set { SetValue(LabelProperty, value); } } // Using a DependencyProperty as the backing store for Label. This enables animation, styling, binding, etc... public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(object), typeof(KDLayoutItem), new PropertyMetadata(null)); public double GetLabelWidht() { return (this.Template.FindName("lbl",this) as Label).ActualWidth; } public void SetLabelWidht(double width) { (this.Template.FindName("lbl", this) as Label).SetValue(WidthProperty,width); } }
功能类似dev的layoutcontrol,layoutgroup,layoutitem.
用法如下:
<Window x:Class="AutoWidthTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:AutoWidthTest" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <local:KDLayoutControl> <local:KDLayoutGroup Height="50" VerticalAlignment="Top" Margin="3"> <local:KDLayoutItem Label="aaa"> <TextBox /> </local:KDLayoutItem> <local:KDLayoutItem Label="bbb"> <TextBox /> </local:KDLayoutItem> <local:KDLayoutItem Label="ccc"> <TextBox /> </local:KDLayoutItem> </local:KDLayoutGroup> <local:KDLayoutGroup Height="50" VerticalAlignment="Top" Margin="3"> <local:KDLayoutItem Label="number"> <TextBox /> </local:KDLayoutItem> <local:KDLayoutItem Label="name"> <TextBox /> </local:KDLayoutItem> <local:KDLayoutItem Label="age"> <TextBox /> </local:KDLayoutItem> </local:KDLayoutGroup> <local:KDLayoutGroup Height="50" VerticalAlignment="Top" Margin="3"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <local:KDLayoutItem Label="a"> <TextBox /> </local:KDLayoutItem> <local:KDLayoutItem Label="b" Grid.Column="1" Grid.ColumnSpan="2"> <TextBox /> </local:KDLayoutItem> </Grid> </local:KDLayoutGroup> </local:KDLayoutControl> </Window>
不管label字段有多长,KDLayoutControl会设置容器内所有的label长度一致。