WinUI3:如何将ListBox高度按比例绑定到Button的Maxlength属性
解决方案
说明
首先明确:Button控件本身没有MaxLength属性,该属性属于TextBox类。如果你的需求是限制Button内部输入内容的字符长度,需要将Button的Content替换为TextBox;如果是笔误想设置Button的MaxHeight(最大高度),只需修改绑定的目标属性即可。以下方案基于你描述的需求实现,同时避免使用Grid、StackPanel等布局面板。
步骤1:修改XAML结构
移除原有的Grid,直接将ListBox作为Window的Content,后续通过代码添加Button到装饰层(AdornerLayer)以避免使用布局面板:
<Window x:Class="App1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:App1" Loaded="Window_Loaded"> <ListBox x:Name="listBox" /> </Window>
步骤2:创建值转换器
实现IValueConverter接口,将ListBox的高度值乘以0.4后转换为整数(因为MaxLength是int类型):
using System; using System.Globalization; using System.Windows.Data; namespace App1 { public class HeightToMaxLengthConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value is double height) { return (int)(height * 0.4); } return 0; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } }
步骤3:后台代码添加Button并绑定属性
在Window的Loaded事件中,创建Button并将其添加到AdornerLayer(无需布局面板即可定位),同时通过绑定+转换器实现高度到MaxLength的转换:
using System.Windows; using System.Windows.Controls; using System.Windows.Documents; namespace App1 { public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void Window_Loaded(object sender, RoutedEventArgs e) { // 创建Button(若需输入功能,可将Content替换为TextBox) Button button = new Button { Name = "button", Content = "Click me!" }; // 绑定ListBox的ActualHeight到目标属性 var converter = new HeightToMaxLengthConverter(); Binding binding = new Binding("ActualHeight") { Source = listBox, Converter = converter, Mode = BindingMode.OneWay }; // 若需限制Button内容的输入长度,需将Content改为TextBox并绑定其MaxLength // TextBox inputBox = new TextBox { Text = "Click me!" }; // inputBox.SetBinding(TextBox.MaxLengthProperty, binding); // button.Content = inputBox; // 若为笔误想设置Button的最大高度,绑定此属性 // button.SetBinding(Button.MaxHeightProperty, binding); // 将Button添加到AdornerLayer,自定义位置 AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(listBox); adornerLayer.Add(new ButtonAdorner(listBox, button)); } } // 自定义Adorner用于放置Button public class ButtonAdorner : Adorner { private readonly Button _button; public ButtonAdorner(UIElement adornedElement, Button button) : base(adornedElement) { _button = button; AddVisualChild(_button); } protected override int VisualChildrenCount => 1; protected override Visual GetVisualChild(int index) { if (index != 0) throw new ArgumentOutOfRangeException(); return _button; } protected override Size MeasureOverride(Size constraint) { _button.Measure(constraint); return _button.DesiredSize; } protected override Size ArrangeOverride(Size finalSize) { // 自定义Button的位置,示例为ListBox下方 _button.Arrange(new Rect(0, AdornedElement.DesiredSize.Height, _button.DesiredSize.Width, _button.DesiredSize.Height)); return finalSize; } } }
关键说明
- AdornerLayer的作用:无需使用布局面板即可在现有控件上方/下方添加新控件,完全自定义位置。
- 属性绑定逻辑:通过
ActualHeight获取ListBox的实际渲染高度,经转换器计算后绑定到目标属性。 - MaxLength的注意点:若需限制输入长度,必须将Button的Content替换为TextBox,因为Button本身不具备该属性。
内容的提问来源于stack exchange,提问作者unsealed1051
相关产品推荐
相关产品推荐

