使用Caliburn Micro 1.5.1我试图让设计时绑定在WP8应用程序中运行。我创建了一个设计时ViewModel,我在PhoneApplicationPage中明确指定:
<phone:PhoneApplicationPage
d:DataContext="{Binding Source={d:DesignInstance Type=designTime:StartPageDesignTimeViewModel, IsDesignTimeCreatable=True}}"
micro:Bind.AtDesignTime="True"
该页面实际上只不过是来自Telerik的RadDataBoundListBox:
<Grid x:Name="ContentPanel">
<telerikPrimitives:RadDataBoundListBox x:Name="Rooms" ...>
如您所见,我的ViewModel(和设计时视图模型)有一个名为Rooms的公共属性,我使用命名的约定方法绑定到ItemsSource集合。但是,除非我添加ItemsSource属性
,否则该方法在设计时不起作用<Grid x:Name="ContentPanel">
<telerikPrimitives:RadDataBoundListBox x:Name="Rooms" ItemsSource="{Binding Rooms}" ...>
然而,当我使用ItemsSource绑定时,我失去了像SelectedItem这样的CM连接魔法。有没有办法让我的绑定在设计时使用命名约定方法工作,而无需使用除设计时属性之外的任何内容修改页面?
答案 0 :(得分:2)
好的,我明白了。我一直在寻找能够随时覆盖现有绑定的能力。 CM比这更具防御性,因此默认情况下它不会替换ItemsControl的现有绑定或值。这种行为在ConventionManager.cs中定义:
AddElementConvention<ItemsControl>(ItemsControl.ItemsSourceProperty, "DataContext", "Loaded")
.ApplyBinding = (viewModelType, path, property, element, convention) => {
if (!SetBindingWithoutBindingOrValueOverwrite(viewModelType, path, property, element, convention, ItemsControl.ItemsSourceProperty)) {
return false;
}
ApplyItemTemplate((ItemsControl)element, property);
return true;
};
我强制框架始终替换绑定的做法是在我的BootStrapper中直接调用SetBindingWithoutBindingOrValueOverwrite
来替换对SetBinding
的调用。所以:
ConventionManager.AddElementConvention<ItemsControl>(ItemsControl.ItemsSourceProperty, "DataContext", "Loaded")
.ApplyBinding = (viewModelType, path, property, element, convention) => {
ConventionManager.SetBinding(viewModelType, path, property, element, convention, ItemsControl.ItemsSourceProperty);
ConventionManager.ApplyItemTemplate((ItemsControl) element, property);
return true;
};
(我还必须对我之前为RadDataBoundListBox添加的约定进行编辑)
在某些情况下,我可以看到有人可能想要声明性地强制替换现有绑定。也许我会写一个补丁...