如何为NumberBox、AutoSuggestBox等类TextBox控件实现ReadOnly行为?
实现NumberBox、AutoSuggestBox等控件的只读(ReadOnly)行为
先明确Microsoft.UI.Xaml.Controls.TextBox的IsReadOnly属性和!IsEnabled的核心差异:
- 只读状态下内容可被选中复制
- 只读控件默认支持Tab键聚焦
- 外观和非只读状态几乎一致
而NumberBox、AutoSuggestBox这类控件没有内置的IsReadOnly属性,要实现同等效果,可以按以下方式处理:
一、NumberBox的只读实现
要保留聚焦、选中文本的能力,同时禁止修改,且保持原有外观,可通过拦截输入事件实现:
XAML代码
<NumberBox x:Name="ReadOnlyNumberBox" IsEnabled="True" PointerPressed="ReadOnlyNumberBox_PointerPressed" KeyDown="ReadOnlyNumberBox_KeyDown"/>
后台C#代码
private void ReadOnlyNumberBox_PointerPressed(object sender, PointerRoutedEventArgs e) { if (sender is NumberBox numberBox) { // 点击时自动全选文本,同时阻止进入编辑状态 numberBox.SelectAll(); e.Handled = true; } } private void ReadOnlyNumberBox_KeyDown(object sender, KeyRoutedEventArgs e) { // 拦截所有修改类按键,禁止内容变更 e.Handled = true; }
注意不要用IsEnabled="False",会导致控件灰化且无法选中内容;也不要用IsEditable="False",会改变控件的默认外观。
二、AutoSuggestBox的只读实现
AutoSuggestBox的核心交互依赖内部的TextBox控件,直接操作内部TextBox的IsReadOnly属性即可:
方法1:通过自定义模板设置
<AutoSuggestBox x:Name="ReadOnlyAutoSuggestBox" IsEnabled="True"> <AutoSuggestBox.Template> <ControlTemplate TargetType="AutoSuggestBox"> <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"> <!-- 保留AutoSuggestBox的默认布局,仅修改内部TextBox的IsReadOnly属性 --> <Border x:Name="LayoutRoot" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}"> <Grid> <TextBox x:Name="TextBox" IsReadOnly="True" Text="{TemplateBinding Text}" PlaceholderText="{TemplateBinding PlaceholderText}" Style="{TemplateBinding TextBoxStyle}"/> <Button x:Name="DeleteButton" Visibility="Collapsed" Style="{StaticResource AutoSuggestBoxDeleteButtonStyle}"/> </Grid> </Border> <Popup x:Name="SuggestionsPopup"> <ListView x:Name="SuggestionsList" Style="{StaticResource AutoSuggestBoxListViewStyle}"/> </Popup> </Grid> </ControlTemplate> </AutoSuggestBox.Template> </AutoSuggestBox>
方法2:通过代码获取内部TextBox设置
private void SetAutoSuggestBoxReadOnly(AutoSuggestBox autoSuggestBox) { // 找到AutoSuggestBox内部的TextBox控件 if (autoSuggestBox.FindName("TextBox") is TextBox internalTextBox) { internalTextBox.IsReadOnly = true; } // 确保控件本身保持启用状态,支持聚焦和选中文本 autoSuggestBox.IsEnabled = true; }
调用这个方法后,AutoSuggestBox的文本框会进入只读状态,同时保留原有外观和聚焦、选中文本的能力。
通用实现思路
对于所有无IsReadOnly属性的类TextBox控件,实现同等效果的核心逻辑是:
- 保持控件
IsEnabled="True",确保能被Tab聚焦、选中文本 - 通过拦截输入事件或修改内部文本控件属性,禁止内容修改
- 避免使用禁用状态,保持控件原有外观
内容的提问来源于stack exchange,提问作者Josh Brunton
相关产品推荐
相关产品推荐

