Cod*_*ior 4 data-binding wpf combobox datatemplate
美好的一天,
我有一个通过CollectionViewSource填充的组合框。通过传入项目类型的数据模板(在本例中为ProjectViewModel)构建项目。这是.NET 4.0中的WPF。
在我的window.resources中,我指定了以下内容:
<Style TargetType="{x:Type ComboBoxItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
</Style>
Run Code Online (Sandbox Code Playgroud)
尽管有这种风格,我仍然遇到以下错误:
System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''的绑定源。BindingExpression:Path = HorizontalContentAlignment; DataItem = null; 目标元素是'ComboBoxItem'(Name =''); 目标属性为“ HorizontalContentAlignment”(类型为“ HorizontalAlignment”)
System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''的绑定源。BindingExpression:Path = VerticalContentAlignment; DataItem = null; 目标元素是'ComboBoxItem'(Name =''); 目标属性为“ VerticalContentAlignment”(类型为“ VerticalAlignment”)
我也对ComboBox元素指定了水平和垂直ContentAlignment,但无济于事。这不是一个严重的问题,因为项目正确显示。但是,在调试时,关闭窗口时确实会延迟约10秒钟,同时它将大约4000条错误消息输出到输出窗口(我需要打开它才能捕获合法的绑定错误。
我可能无法正确读取错误。为什么找不到绑定的有效来源?据我所知,我使用ComboBox和CollectionViewSource的方式符合他们的意图。
我以为我已经在自己的程序中解决了这个问题,但是发现它不断间歇地弹出。最终设法找到问题的根源。
如果您使用的是带有的组合框ICollectionView,并且collectionView.Refresh()在事件队列上堆叠了两个或多个调用(例如,由于两次不同的清除操作而调用两次刷新),这将导致它在上生成垃圾邮件绑定错误每个附加Refresh()调用的组合框的每个元素。仅在您至少打开一次组合框之后,才会发生此绑定错误。
重写它,以便只Refresh()给定事件调用一次,这样可以防止出现绑定错误。
我只想提一下我在这个问题上挣扎了两天。最常见的建议解决方案(将 Horizontal/VerticalContentAlignment 样式添加到元素,甚至 App.xaml)并不总能解决问题。
最终,我发现了一些与我自己的情况不同的东西 - 我希望它可以对某人有所帮助:如果您正在使用 FilterEventHandler,请不要在重新订阅之前取消订阅!
每当我更改通道过滤器(调用 UpdateCorporatesList)时,我的旧代码都会继续生成“数据错误 4”消息:
// This code generates errors
private void UpdateCorporatesList()
{
this.CorporatesViewSource.Filter -= new FilterEventHandler(ApplyCorporateFilter);
if (this.ChannelFilter != null)
{
this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);
}
else
{
this.CorporateFilter = null;
}
}
private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
SalesCorporate customer = e.Item as SalesCorporate;
var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter).Description;
if ((customer.ID != null) && (customer.Channel != currentChannel))
{
e.Accepted = false;
}
}
Run Code Online (Sandbox Code Playgroud)
...所以我将其更改为每次都重新订阅 FilterEventHandler,而是将在事件处理方法中对 Channel Filter 进行 null 检查。
// This code works as intended
private void UpdateCorporatesList()
{
this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);
if (this.ChannelFilter == null)
{
this.CorporateFilter = null;
}
}
private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter);
if (currentChannel.ID == null)
{
return;
}
SalesCorporate customer = e.Item as SalesCorporate;
if ((customer.ID != null) && (customer.Channel != currentChannel.Description))
{
e.Accepted = false;
}
}
Run Code Online (Sandbox Code Playgroud)
瞧瞧!不再有错误:-)
| 归档时间: |
|
| 查看次数: |
3866 次 |
| 最近记录: |