2016-12-03 11 views
1

私はアイコンとテキストを表示することUserControlシンプルを持っている:コードビハインド別のUserControl内のUserControlのプロパティにバインドする方法は?

<UserControl x:Class="IconLabel" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     mc:Ignorable="d" 
     d:DesignHeight="26" d:DesignWidth="200" DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="Auto"/> 
      <ColumnDefinition Width="1*"/> 
     </Grid.ColumnDefinitions> 
     <Image x:Name="imgIcon" Source="{Binding Path=IconPath}" Stretch="UniformToFill" Width="26" Height="26" Margin="3,0" /> 
     <Label Content="{Binding Path=LabelText}" Margin="5,0" Grid.Column="1" /> 
    </Grid> 
</UserControl> 

は、外部から拘束されることを意図されている2つのDependencyPropertiesを定義しています。これまでの罰金働いて

Public Class IconLabel 

    Public Property IconPath As String 
     Get 
      Return GetValue(IconPathProperty) 
     End Get 
     Set(ByVal value As String) 
      SetValue(IconPathProperty, value) 
     End Set 
    End Property 

    Public Shared ReadOnly IconPathProperty As DependencyProperty = DependencyProperty.Register("IconPath", GetType(String), GetType(IconLabel), New PropertyMetadata("")) 

    Public Property LabelText As String 
     Get 
      Return GetValue(LabelTextProperty) 
     End Get 
     Set(ByVal value As String) 
      SetValue(LabelTextProperty, value) 
     End Set 
    End Property 

    Public Shared ReadOnly LabelTextProperty As DependencyProperty = DependencyProperty.Register("LabelText", GetType(String), GetType(IconLabel), New PropertyMetadata("LabelText")) 
End Class 

。私は、XAMLでプロパティを設定することができ、それらは適切に慣れている:

<local:IconLabel LabelText="Test"/> 

しかし、私は今少しプログレスバーを示すことによって、その機能を拡張し、別のUserControlで再使用し、この制御したいのですが次の(私は例のために、この短いを守ってきた)、それを次のコードビハインドで

<UserControl x:Class="IconLabelProgress" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:local="clr-namespace:myApp" 
     mc:Ignorable="d" 
     d:DesignHeight="26" d:DesignWidth="600" DataContext="{Binding RelativeSource={RelativeSource Self}}"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="4*" MaxWidth="300"/> 
      <ColumnDefinition Width="6*"/> 
     </Grid.ColumnDefinitions> 
     <local:IconLabel IconPath="{Binding Path=IconPath}" LabelText="{Binding Path=PropName}" /> 
     <ProgressBar Value="{Binding Path=ActualValue}" Minimum="0" Maximum="10" Margin="5" Height="16" VerticalAlignment="Top" Grid.Column="1" /> 
    </Grid> 
</UserControl> 

Public Class IconLabelProgress 

    'These are just meant to be passed along to the IconLabel 
    Public Property IconPath As String 
     Get 
      Return GetValue(IconPathProperty) 
     End Get 
     Set(ByVal value As String) 
      SetValue(IconPathProperty, value) 
     End Set 
    End Property 

    Public Shared ReadOnly IconPathProperty As DependencyProperty = DependencyProperty.Register("IconPath", GetType(String), GetType(IconLabelProgress), New PropertyMetadata("")) 

    Public Property PropName As String 
     Get 
      Return GetValue(PropNameProperty) 
     End Get 
     Set(ByVal value As String) 
      SetValue(PropNameProperty, value) 
     End Set 
    End Property 

    Public Shared ReadOnly PropNameProperty As DependencyProperty = DependencyProperty.Register("PropName", GetType(String), GetType(IconLabelProgress), New PropertyMetadata("PropName")) 

    'This one is new 
    Public Property ActualValue As Double 
     Get 
      Return GetValue(ActualValueProperty) 
     End Get 
     Set(ByVal value As Double) 
      SetValue(ActualValueProperty, value) 
     End Set 
    End Property 

    Public Shared ReadOnly ActualValueProperty As DependencyProperty = DependencyProperty.Register("ActualValue", GetType(Double), GetType(IconLabelProgress), New PropertyMetadata(0.0)) 
End Class 

私は今、このコントロールをインスタンス化し、このように、インナーIconLabelコントロールのラベルの値を渡すしようとした場合:

<local:IconLabelProgress x:Name="ilp1" PropName="Test" ActualValue="5.0" /> 

それはそのラベルに「テスト」を表示されません、代わりにフォールバックPropertyMetadata("LabelText")で指定された既定値に変更します。しかし、ActualValueは正しく使用されます。

外部コントロールが値をネストされたコントロールに渡すようにするにはどうすればよいですか?

答えて

2

は、例えば、UserControlの親からのDataContextを継承しないようにここに

<local:IconLabel LabelText="{Binding Path=PropName}" ... /> 

ここで、PropNameは親DataContextのプロパティであると予想されます。代わりに、明示的にUserControlのDataContextは、とその "内部" バインディングを書き込む設定の


RelativeSource

よう
<Label Content="{Binding Path=LabelText, 
       RelativeSource={RelativeSource AncestorType=UserControl}}" ... /> 
+0

も参照[この回答](のhttp://のstackoverflow。com/a/40674448/1136211)。 – Clemens

+0

これは私にとってはうまくいかないようです。 'DataContext'を取り除き、' RelativeSource'を直接設定することによって、 'IconLabel'は直接(外の' IconLabelProgress'を使わずに)それを使う時に値を表示しません。 'Label'の内容は空白のままです。 –

+0

申し訳ありませんが、私の悪い。 'RelativeSource Self'を' RelativeSource AncestorType = UserControl'に置き換えてください。 – Clemens

0

既定で(ほかに何も指定していない)、バインディングはオブジェクトDataContextから解決されます。したがって、IconLabelはという名前のプロパティーをDataContextに検索します。プロパティを検索する場所が外部制御され、あなたが結合にElementNameを追加し、IconLabelProgressに名前プロパティを設定したり、How do I use WPF bindings with RelativeSourceで受け入れ答えの第二の例のようにRelativeSourceを指定することができるように指定するには

希望します。あなたは

<UserControl x:Class="IconLabel" ... 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

でとても効果的に行うかのように明示的にユーザーコントロールのDataContextプロパティを設定することはありません一般的なルールとして

関連する問題