11

I am trying to bind a dependency property via XAML to my custom WPF control.

Here's how I register the dependency property:

public static readonly DependencyProperty AltNamesProperty = 
    DependencyProperty.Register ("AltNames", typeof(string), typeof(DefectImages));

public string AltNames
{
    get { return (string) GetValue(AltNamesProperty); }
    set { SetValue(AltNamesProperty, value); }
}

And Here's how I call it in my XAML:

<DataGrid.Columns>                
    <DataGridTemplateColumn IsReadOnly="True">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <StackPanel Name="StackPanel1" Grid.Column="0" Width="950">
                    <TextBlock FontSize="16" TextDecorations="None" Text="{BindingPath=StandardName}" Foreground="Black"  FontWeight="Bold" Padding="5,10,0,0"></TextBlock>
                    <TextBlock Text="{Binding Path=AltNames}"TextWrapping="WrapWithOverflow" Padding="5,0,0,10"></TextBlock>
                    <!-- this part should be magic!! -->
                    <controls:DefectImages AltNames="{Binding Path=AltNames}"></controls:DefectImages>
                </StackPanel>
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
</DataGrid.Columns>

I know the AltNames property that I'm attempting to bind to is a valid property because I can display it in a textblock just fine. Am I registering the Dependency property incorrectly?

What do I need to do to get the correct value assigned to AltNames in my code behind?

CD Smith
  • 6,579
  • 7
  • 38
  • 65
jacobsimeon
  • 1,874
  • 1
  • 17
  • 20
  • Have you tried `AltNames="{Binding Path=AltNames, Mode=TwoWay}"`? Are there any binding errors in the output window during runtime? – nemesv Jun 01 '12 at 21:20
  • @nemesv just tried the two way binding, with no luck. There are no binding errors in the output window. – jacobsimeon Jun 01 '12 at 21:26
  • It is likely this is getting confused by 2 properties sharing the same name. Did you try renaming one? The workaround you flagged as an answer seems whacky! – Gusdor Jun 07 '13 at 10:32
  • In my case, the property was not set inside my `UserControl`'s constructor, but it was in the `Loaded` event. – Walter Stabosz Jan 23 '18 at 20:25

2 Answers2

19

Thanks to @Danko for getting me started. I registered a callback to set the value when the property changes.
Here's what I finally ended up with:

private static void OnDefectIdChanged(DependencyObject defectImageControl, DependencyPropertyChangedEventArgs eventArgs)
{
  var control = (DefectImages) defectImageControl;
  control.DefectID = (Guid)eventArgs.NewValue;
}

/// <summary>
/// Registers a dependency property, enables us to bind to it via XAML
/// </summary>
public static readonly DependencyProperty DefectIdProperty = DependencyProperty.Register(
    "DefectID",
    typeof (Guid),
    typeof (DefectImages),
    new FrameworkPropertyMetadata(
      // use an empty Guid as default value
      Guid.Empty,
      // tell the binding system that this property affects how the control gets rendered
      FrameworkPropertyMetadataOptions.AffectsRender, 
      // run this callback when the property changes
      OnDefectIdChanged 
      )
    );

/// <summary>
/// DefectId accessor for for each instance of this control
/// Gets and sets the underlying dependency property value
/// </summary>
public Guid DefectID
{
  get { return (Guid) GetValue(DefectIdProperty); }
  set { SetValue(DefectIdProperty, value); }
}
jacobsimeon
  • 1,874
  • 1
  • 17
  • 20
2

Maybe you need to specify the PropertyMetadata argument to DependencyProperty.Register, if the property affects how the control is rendered. For example:

DependencyProperty.Register("AltNames", typeof(string), typeof(DefectImages), 
                              new FrameworkPropertyMetadata( null,
                              FrameworkPropertyMetadataOptions.AffectsRender ) );
Danko Durbić
  • 6,887
  • 5
  • 33
  • 38
  • Tried this, and it's still not going for me. I placed a breakpoint on the setter for the AltNames property and it never gets executed. – jacobsimeon Jun 01 '12 at 22:37
  • 2
    Well, the setter is actually never executed, because binding is performed "behind the scenes". You could try [this PropertyMetadata constructor](http://msdn.microsoft.com/en-us/library/ms557327.aspx) to specify a callback method which is executed when the property is changed. Also, check out [How can I debug WPF bindings?](http://bea.stollnitz.com/blog/?p=52). – Danko Durbić Jun 01 '12 at 22:48
  • that's exactly what I just did. Using the callback to set the value worked for me. Thanks for getting me on the right track. – jacobsimeon Jun 01 '12 at 22:57