2012-03-16 65 views
0

我不明白爲什麼綁定工作的文本框,但不適用於usercontrol。 在下面的圖片中,您會看到它應該如何工作。該服務可以綁定到黃色的用戶控件,並且此用戶控件包含我自己的類的屬性。在我的情況下,這個屬性被稱爲電子郵件。問題是,這電子郵件永遠不會綁定到黃色的用戶控件。 如果我通過簡單的「TextBox」控件替換usercontrol,它就可以正常工作。如何設置datacontext和自定義usercontrol綁定

請你能指教我如何獲得綁定工作?跟蹤屬性時的Silvelright主頁

#Region "UserProfile" 

    ''' <summary> 
    ''' UserProfile Dependency Property 
    ''' </summary> 
    Public Shared ReadOnly UserProfileProperty As DependencyProperty = _ 
     DependencyProperty.Register("UserProfile", GetType(ServiceReference1.UserProfile), GetType(MainPage), _ 
      New Windows.PropertyMetadata(Nothing, _ 
       AddressOf OnUserProfileChanged)) 

    ''' <summary> 
    ''' Gets or sets the UserProfile property. This dependency property 
    ''' indicates .... 
    ''' </summary> 
    Public Property UserProfile() As ServiceReference1.UserProfile 
     Get 
      Return CType(GetValue(UserProfileProperty), ServiceReference1.UserProfile) 
     End Get 
     Set(ByVal value As ServiceReference1.UserProfile) 
      SetValue(UserProfileProperty, value) 
     End Set 
    End Property 

    ''' <summary> 
    ''' Handles changes to the UserProfile property. 
    ''' </summary> 
    Private Overloads Shared Sub OnUserProfileChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs) 
     Dim target As MainPage = CType(d, MainPage) 
     Dim oldUserProfile As ServiceReference1.UserProfile = CType(e.OldValue, ServiceReference1.UserProfile) 
     Dim newUserProfile As ServiceReference1.UserProfile = target.UserProfile 
     target.OnUserProfileChanged(oldUserProfile, newUserProfile) 
    End Sub 

    ''' <summary> 
    ''' Provides derived classes an opportunity to handle changes to the UserProfile property. 
    ''' </summary> 
    Protected Overridable Overloads Sub OnUserProfileChanged(ByVal oldUserProfile As ServiceReference1.UserProfile, ByVal newUserProfile As ServiceReference1.UserProfile) 
     Me.DataContext = newUserProfile 

    End Sub 

#End Region 

User control description of binding

代碼隱藏的 「newUserProfile」 項目在代碼隱藏設置成功。

XAML

<UserControl x:Class="CH_App.ucUserEditor" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:my="clr-namespace:CH_App" 

    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBox Text="{Binding Path=Email}"/> 
     <my:ucDbRow Title="Email" Value="{Binding Path=Email, Mode=TwoWay}" /> 
    </Grid> 
</UserControl> 

的Texbox與電子郵件的結合就像它應該和顯示的電子郵件地址。 usercontrol不顯示電子郵件地址。用戶控件顯示標題正確。

用戶控件

<UserControl x:Class="CH_App.ucDbRow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:my="clr-namespace:CH_App" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
      DataContext="{Binding RelativeSource={RelativeSource Self}}" 
    d:DesignHeight="300" d:DesignWidth="400"> 

    <StackPanel> 
     <TextBlock x:Name="txtTitle" Text="{Binding Path=Title}" /> 
     <TextBox x:Name="txtValue" Text="{Binding Path=Value, Mode=TwoWay}"/> 
    </StackPanel> 
</UserControl> 

用戶控件的代碼隱藏

#Region "Title" 

    ''' <summary> 
    ''' Title Dependency Property 
    ''' </summary> 
    Public Shared ReadOnly TitleProperty As DependencyProperty = _ 
     DependencyProperty.Register("Title", GetType(String), GetType(ucDbRow), _ 
      New Windows.PropertyMetadata("")) 

    ''' <summary> 
    ''' Gets or sets the Title property. This dependency property 
    ''' indicates .... 
    ''' </summary> 
    Public Property Title() As String 
     Get 
      Return CType(GetValue(TitleProperty), String) 
     End Get 
     Set(ByVal value As String) 
      SetValue(TitleProperty, value) 
     End Set 
    End Property 

#End Region 



#Region "Value" 

    ''' <summary> 
    ''' Value Dependency Property 
    ''' </summary> 
    Public Shared ReadOnly ValueProperty As DependencyProperty = _ 
     DependencyProperty.Register("Value", GetType(String), GetType(ucDbRow), _ 
      New Windows.PropertyMetadata("")) 

    ''' <summary> 
    ''' Gets or sets the Value property. This dependency property 
    ''' indicates .... 
    ''' </summary> 
    Public Property Value() As String 
     Get 
      Return CType(GetValue(ValueProperty), Object) 
     End Get 
     Set(ByVal value As String) 
      SetValue(ValueProperty, value) 
     End Set 
    End Property 

#End Region 
+0

這是一個WPF問題或Silverlight問題? – NVM 2012-03-16 13:28:59

+0

我正在Silverlight上工作。但上個月,我在WPF上遇到了類似的問題,但是我在那裏沒有綁定。現在我想解決它,因爲我確信,我錯過了一小段聲明。我現在用不同的綁定關鍵字嘗試了幾個小時,但它從來沒有奏效。 – Nasenbaer 2012-03-16 13:33:10

+0

我兩次閱讀這個問題,仍然沒有得到你想要做的。提供你想要首先實現的細節。 – NVM 2012-03-16 13:42:09

回答

1

編輯(插入):

您使用Silverlight 4中,我要麼在測試從中獲得Silverlight 5或WPF b或許,但
WPF肯定支持RelativeSourceBinding這種方式,但你幾乎是正確的。
如果我是正確的,Visual Studio中的輸出窗口會給你以下錯誤。

System.Windows.Data Error: BindingExpression path error:
'Email' property not found on 'VisualBasicSilverlightApplication1.ucDbRow'
'VisualBasicSilverlightApplication1.ucDbRow' (HashCode=72766).
BindingExpression: Path='DataContext.Email'
DataItem='VisualBasicSilverlightApplication1.ucDbRow' (HashCode=72766);
target element is 'VisualBasicSilverlightApplication1.ucDbRow' (Name='');
target property is 'Value' (type 'System.String')..

DataContext將落在usercontrol中,除了usercontrol的頂級/實例。
因此,而不是這樣做:

<my:ucDbRow Title="Email" Value="{Binding Path=Email, Mode=TwoWay}" /> 

你將不得不在你的代碼改變的唯一事情是指向您設置的DataContext的元素,這是大多數時間LayoutRoot:
(在ucUserEditor)

<my:ucDbRow Title="Email" Value="{Binding ElementName=LayoutRoot, 
      Path=DataContext.Email, Mode=TwoWay}" /> 

以前的答案
要覆蓋本DataContext="{Binding RelativeSource={RelativeSource Self}}"在CH_App.ucDbRow綁定的DataContext的。刪除它,價值工作,因爲你已經得到你的underlaying DataContext回來,但標題不再工作。

有一個解決方案:

變化ucDbRow這樣:

<UserControl x:Class="CH_App.ucDbRow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400"> 
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding}"> 
    <StackPanel> 
     <TextBlock x:Name="txtTitle" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Title}" Height="23"/> 
     <TextBox x:Name="txtValue" Text="{Binding Path=Value, Mode=TwoWay}"/> 
    </StackPanel> 
    </Grid> 
</UserControl> 

注意:檢查您的輸出中的窗口,如果綁定不工作,如果它失敗了它在輸出窗口。

另外:

我建議使用UserControl的作爲對照的。在我看來,用戶控件應該更多地用於表示個人情境,而不是一個半環境的另一半。開始將用戶控件更多地視爲頁面,並使用自定義控件和數據模板來進行詳細的工作。使用Grid(也是我認爲的)WPF和Silverlight中最好的功能之一,不能被有序的用戶控件擊敗,因此構建更好的佈局變得非常容易。

+0

嗨Silvermind。感謝您的回答。我與你在usercontrols上,但它會擴大這個問題,如果我在這裏解釋一切。我也做了堆棧面板只是爲了問題。我是AncestorType使用中的新成員,並且在Silverlight XAML ucDbRow中輸入AncestorType時未找到相關源,我已收到ERROR消息。有什麼建議? – Nasenbaer 2012-03-18 16:39:46

+0

@Nasenbaer因爲它需要你的命名空間。 xmnls:local =「clr-namespace:mynamespace」and Ancestortype =「{x:Type local:ucDbRow}」 – Silvermind 2012-03-18 16:47:06

+0

Btw:如果ucDbRow是一個UserControl(如你的示例xaml中提供的,我假設是),比你還可以指定單詞UserControl作爲AncestorType。 – Silvermind 2012-03-18 18:13:30

相關問題