WPF附加属性绑定TwoWay时Intellisense提示“No DataContext found”问题
Intellisense误报“TwoWay绑定无DataContext”的原因(附加属性场景)
问题现象
开发的UserControl中,ItemsPanelTemplate内的Grid使用了两个自定义附加属性local:GridSetUp.WeekView和local:GridSetUp.GridData,绑定代码如下:
<ItemsPanelTemplate> <Grid Name="WeekViewGrid" Width="Auto" Height="Auto" HorizontalAlignment="Left" local:GridSetUp.WeekView="{Binding TheWeek.Days, Mode=TwoWay}" local:GridSetUp.GridData="{Binding TheGridData, Mode=TwoWay}" IsSharedSizeScope="True"> </Grid> </ItemsPanelTemplate>
Intellisense会标记绑定中的TwoWay,提示“No DataContext found for binding TwoWay”,但实际绑定到DataContext的TheWeek.Days和TheGridData功能完全正常,且Mode语法符合标准。
附加属性的注册代码如下:
WeekView附加属性
public static DependencyProperty WeekViewProperty = DependencyProperty.RegisterAttached( "WeekView", typeof(ObservableCollection<Day>), typeof(GridSetUp), new PropertyMetadata(new ObservableCollection<Day> { }, WeekViewChanged)); public static ObservableCollection<Day> GetWeekView(Grid grid) { return (ObservableCollection<Day>)grid.GetValue(WeekViewProperty); } public static void SetWeekView(Grid grid, ObservableCollection<Day> value) { grid.SetValue(WeekViewProperty, value); }
GridData附加属性
public static DependencyProperty GridDataProperty = DependencyProperty.RegisterAttached( "GridData", typeof(GridData), typeof(GridSetUp), new PropertyMetadata(new GridData(), GridDataChanged)); public static GridData GetGridData(Grid grid) { return (GridData)grid.GetValue(GridDataProperty); } public static void SetGridData(Grid grid, GridData value) { grid.SetValue(GridDataProperty, value); } public static void GridDataChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) { }
原因分析
这是Visual Studio Intellisense的静态分析误报,核心原因在于:
- 附加属性注册时使用的是
PropertyMetadata,没有显式通过FrameworkPropertyMetadata标记该属性支持双向绑定(即未设置FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)。 - Intellisense在解析XAML绑定表达式中的
Mode=TwoWay时,出现了逻辑混淆,错误地将Mode本身当成了需要绑定到DataContext的目标属性,而非绑定表达式的配置项,因此抛出“找不到DataContext”的提示。 - 运行时WPF的绑定引擎能正确识别整个绑定表达式的结构,不受Intellisense静态分析的影响,所以实际功能完全正常。
消除提示的方案
如果要让Intellisense停止误报,可以修改附加属性的注册代码,使用FrameworkPropertyMetadata并添加BindsTwoWayByDefault选项,明确告知Intellisense该属性支持双向绑定:
// 修改WeekViewProperty注册 public static DependencyProperty WeekViewProperty = DependencyProperty.RegisterAttached( "WeekView", typeof(ObservableCollection<Day>), typeof(GridSetUp), new FrameworkPropertyMetadata( new ObservableCollection<Day>(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, WeekViewChanged)); // 修改GridDataProperty注册 public static DependencyProperty GridDataProperty = DependencyProperty.RegisterAttached( "GridData", typeof(GridData), typeof(GridSetUp), new FrameworkPropertyMetadata( new GridData(), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, GridDataChanged));
内容的提问来源于stack exchange,提问作者user3486991
相关产品推荐
相关产品推荐

