我正在使用WPF SQL Connection User Control。每当我在一个已打开,关闭然后再打开的选项卡(AvalonDock DocumentTab )上抛出 StackOverflowException 时,我遇到了一个问题。< / p>
我已经搞砸了Jake的基础实现以更好地适应我的应用程序,但它基本上是相同的。我添加了一个禁用数据库选择的属性。
我已将控件放入我的应用程序中:
<controls:SqlConnectionStringBuilder
Grid.Row="2"
Margin="0,10,0,0"
ConnectionString="{Binding ElementName=listBoxClients,
Path=SelectedItem.ConnectionString,
UpdateSourceTrigger=PropertyChanged}"
Header="Connection String"
RequireDatabase="True" />
我已经对SqlConnectionStringBuilder的代码隐藏进行了一些重构,以便解决这个问题,但这似乎是违规的代码:
public static readonly DependencyProperty ConnectionStringProperty =
DependencyProperty.Register(
"ConnectionString",
typeof(SqlConnectionString),
typeof(SqlConnectionStringBuilder),
new FrameworkPropertyMetadata(
new SqlConnectionString { IntegratedSecurity = true, Pooling = false },
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public SqlConnectionString ConnectionString
{
get { return (SqlConnectionString)GetValue(ConnectionStringProperty); }
set { SetValue(ConnectionStringProperty, value); }
}
在选项卡的第二次打开时,SqlConnectionString
对象使用其OnPropertyChanged
方法和IntegratedSecurity
属性进入无限循环。当我使ConnectionString
属性不是DependencyProperty时,我没有遇到这个问题。对我来说,这说明问题在于依赖属性的默认值。
我在网上捅了一下,看看是否有其他人有这个问题,但似乎我可能已经让自己陷入了一些困境。我可以认为这个问题可能来自于this SO question about dependency properties which was answered as thread safety。我不确定依赖属性如何处理它们的默认值,但我可以看到,如果同一个对象连接了OnPropertyChanged
事件的两倍问题。然而,这也让我相信,如果是这种情况,这个问题会在某个地方被注意到!
有什么想法吗?
其他信息:
我从依赖项属性的注册中删除了默认值(将其设置为null)。这可以防止问题发生。此解决方案的唯一缺点是UI处于null
状态,没有默认选择。不过,我想通过解决问题来防止这种情况发生。
答案 0 :(得分:2)
每次关闭选项卡时,是否都会注册新的依赖项属性?我很确定如果它所引用的内容已被处理,你就不能重用相同的依赖属性注册。关闭选项卡后,垃圾收集器将尝试使用“ConnectionString”对象。当标签失去范围时,它将处理所有子变量,即使它们是静态只读。
答案 1 :(得分:1)
在那个无限循环中,谁在为响应OnPropertyChanged而对IntegratedSecurity属性进行赋值?如果您发现这是谁,这是您答案的关键。
答案 2 :(得分:0)
可能,添加
if (value != GetValue(ConnectionStringProperty))
设置者中的会阻止它。