使用下划线助记符时WPF Button绑定的Content首次加载为空问题
问题原因
该问题的核心是Caliburn.Micro(下称CM)的默认命名约定绑定逻辑与WPF的助记符处理逻辑存在执行时序冲突:
- CM对
x:Name="CloseButton"的按钮有内置绑定约定:会自动将按钮的Command绑定到ViewModel中名为Close的方法,同时会自动处理按钮的Content属性值,为其添加默认的助记符格式化逻辑。 - 首次打开对话框时,你自定义的
CloseButtonText绑定执行完成后,CM的约定绑定逻辑会紧接着执行,它识别到属性值包含下划线助记符时,内部格式化逻辑存在缺陷,会临时将Content值置空;第二次打开对话框时,ViewModel已完成初始化,CM会复用之前的缓存值,不会再触发格式化逻辑,因此绑定恢复正常。 - 两种无异常场景的原理:
- 移除下划线后,CM的助记符格式化逻辑不会触发,不会覆盖你绑定的
Content值 - XAML硬编码
Content时,CM的约定绑定优先级低于硬编码属性值,因此不会受到影响
- 移除下划线后,CM的助记符格式化逻辑不会触发,不会覆盖你绑定的
解决方案
以下三种方案均可解决问题,可根据业务场景选择:
- 方案1:禁用当前按钮的CM默认约定
在Button标签中添加属性关闭CM的约定绑定,完全保留你自定义的Content绑定逻辑:
先引入CM命名空间:
修改按钮定义:xmlns:cal="http://www.caliburnproject.org"<Button x:Name="CloseButton" Margin="6" MinWidth="85" Width="Auto" Style="{DynamicResource StandardButton}" Content="{Binding CloseButtonText}" cal:View.Model.ConventionsApplied="False"/> - 方案2:显式指定AccessText承载内容
直接定义按钮的Content为AccessText控件,绕开CM对Content属性的默认处理,同时保留助记符功能:<Button x:Name="CloseButton" Margin="6" MinWidth="85" Width="Auto" Style="{DynamicResource StandardButton}"> <Button.Content> <AccessText Text="{Binding CloseButtonText}"/> </Button.Content> </Button> - 方案3:主动触发属性变更通知
让你的ViewModel继承CM内置的PropertyChangedBase基类,在OnActivate生命周期方法中主动触发CloseButtonText的属性变更通知,覆盖CM首次置空的Content值:public class YourDialogViewModel : PropertyChangedBase { public string CloseButtonText => "_Close"; protected override void OnActivate() { base.OnActivate(); NotifyOfPropertyChange(nameof(CloseButtonText)); } }
内容的提问来源于stack exchange,提问作者Chuck Norris
相关产品推荐
相关产品推荐

