2012-06-29 56 views
0

我創建的公開一個DependencyProperty的用戶控件:DependencyProperty的未分配

namespace MyApp.Sql 
{ 
public partial class SqlConnectionStringBuilder 
{ 
    private static readonly SqlConnectionString DefaultValue = new SqlConnectionString { IntegratedSecurity = true, Pooling = false }; 

    public static readonly DependencyProperty ConnectionStringProperty = 
     DependencyProperty.Register("ConnectionString", typeof(SqlConnectionString), 
            typeof (SqlConnectionStringBuilder), 
            new FrameworkPropertyMetadata(
             DefaultValue, 
             FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
             ConnectionStringChanged)); 



    private static void ConnectionStringChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     var builder = (SqlConnectionStringBuilder) d; 
     if (e.NewValue == null) 
      builder.Dispatcher.BeginInvoke((Action)(() => d.SetValue(ConnectionStringProperty, DefaultValue))); 
     else 
      builder.RegisterNewConnectionString((SqlConnectionString)e.NewValue); 
    } 

    public SqlConnectionString ConnectionString 
    { 
     get { return (SqlConnectionString)GetValue(ConnectionStringProperty); } 
     set { SetValue(ConnectionStringProperty, value); } 
    } 

    private void RegisterNewConnectionString(SqlConnectionString newValue) 
    { 
     if (newValue != null) 
      newValue.PropertyChanged += ConnectionStringPropertyChanged; 
    } 
    ... 
    } 
} 

現在我嘗試使用ConnectionString在另一個用戶控件並附加一個TextBlock到的ConnectionString:

</UserControl.Resources> 
<Grid Grid.IsSharedSizeScope="True"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="1*" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <MyApp.Sql:SqlConnectionStringBuilder ConnectionString="{Binding ElementName=_this, Path=ServerConnectionString}" /> 
    <TextBlock Text="{Binding ElementName=_this, Path=ServerConnectionString, StringFormat='Produced Connection String: {0}'}" 
       Grid.Row="1" /> 
</Grid> 

namespace MyApp 
{ 
    public partial class SqlProvider 
    { 
    public SqlProvider 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 

    private SqlConnection _connection; 
    public SqlConnection ServerConnectionString 
    { 
     get { return _connection; } 
     set 
     { 
      _connection = value; 
      OnPropertyChanged("ServerConnectionString"); 
     } 
    } 


    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      var e = new PropertyChangedEventArgs(propertyName); 
      handler(this, e); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    } 
} 

但SqlConnectionString永遠不會分配給TextBlock。 當我調試ConnectionStringBuilder的SqlConnection屬性時,它始終顯示爲空

我的錯在哪裏?

+0

您引用的'UserControl'是SqlConnectionStringBuilder,但是您發佈的類是ConnectionStringBuilder,並且不繼承DependencyObject,使DependencyProperty無效,不會繼承UserControl – jimmyjambles

+0

對不起,這是一個複製粘貼misstake ...它的名字是SqlConnectionStringBuilder,它是UserControl的一部分。 – Steve

+0

僅僅因爲它仍然可能是你的代碼不工作的原因,你的SqlConnectionStringBuilder類是否繼承了UserControl? – jimmyjambles

回答

0

檢查你的綁定。我假設你使用SqlConnectionStringBuilder UserControl來創建連接,在這種情況下,它的綁定模式應該是兩種方式。

現在,它看起來像你試圖綁定到你的MainWindow的代碼隱藏。如果您將UserControl的ConnectionString綁定設置爲兩種方式,則對該依賴項屬性所做的任何更改都會被注入到MainWindow的ServerConnectionString屬性中。而且,因爲您的MainWindow實現了INotifyPropertyChanged,所以一旦更新了ServerConnectionString屬性,TextBlock應該更新。另外,如果您綁定到您的MainWindow,則沒有必要在綁定中指定ElementName屬性。由於您在構造函數中設置了DataContext = this,因此您可以在UserControl上說{Binding Path=ServerConnectionString, Mode=TwoWay}

+0

我試圖添加Mode = TwoWay,但這沒有效果。 – Steve

0

如果我使用ElementNames這樣的:

<MyApp.Sql:SqlConnectionStringBuilder x:Name="sqlConnectionStringBuilder" ConnectionString="{Binding ElementName=_this, Path=ServerConnectionString, Mode=TwoWay}" /> 
<TextBlock Text="{Binding ElementName=sqlConnectionStringBuilder, Path=ConnectionString, StringFormat='Produced Connection String: {0}'}" Grid.Row="1" /> 

它的工作原理。

但爲什麼綁定到本地實例不起作用?