Vinay Dwivedi
Vinay Dwivedi

Reputation: 767

Not able to access Datagrid datacontext from datatemplate

DataGrid ItemsSource="{Binding Legs}" Grid.Row="1"
                        DataContext="{Binding}"   
                        Tag="{Binding}"  
                        CanUserAddRows="False"                          
                        CanUserDeleteRows="False" 
                        HorizontalAlignment="Stretch"
                        IsSynchronizedWithCurrentItem="True" 
                        x:Name="statusGrid"  
                        AutoGenerateColumns="False" HorizontalScrollBarVisibility="Hidden"   
                        RowStyle="{StaticResource GridRowStyle}"            
                        >

And then

<DataGrid.Columns>
                        <DataGridTemplateColumn Width="Auto" Header="Status">
                            <DataGridTemplateColumn.CellTemplate>
                                <DataTemplate>
                                    <Image Height="16" MaxHeight="14" Width="14" MaxWidth="14" HorizontalAlignment="Center">
                                        <Image.Source>
                                            <MultiBinding>
                                                <Binding Path="SwapswireBuyerStatusText"/>
                                                <Binding Path="SwapswireSellerStatusText"/>
                                                <MultiBinding.Converter>
                                                    <Control:SwapswireStatusImagePathConvertor AllGoodPath="/Resources/Done.png" 
                                                            InProgressPath="/Resources/Go.png" WarningPath="/Resources/Warning.png">
                                                                **<Control:SwapswireStatusImagePathConvertor.DealProp>
                                                            <Control:DealObject Deal="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=Tag}"/>
                                                                </Control:SwapswireStatusImagePathConvertor.DealProp>**
                                                    </Control:SwapswireStatusImagePathConvertor>
                                                </MultiBinding.Converter>
                                            </MultiBinding>
                                        </Image.Source>
                                    </Image>
                                </DataTemplate>
                            </DataGridTemplateColumn.CellTemplate>
                        </DataGridTemplateColumn>
                    </DataGrid.Columns>

Following is my Depenency property on Convertor

public class DealObject : DependencyObject
    {
        public static DependencyProperty TradedDecimalsProperty =
           DependencyProperty.Register("TradedDecimals", typeof(Int32), typeof(DealObject), new UIPropertyMetadata(0));
        public static DependencyProperty DealProperty =
           DependencyProperty.Register("Deal", typeof(CMBSTrade), typeof(DealObject), new UIPropertyMetadata(new CMBSTrade()));
        public CMBSTrade Deal
        {
            get { return (CMBSTrade)GetValue(DealProperty); }
            set { SetValue(DealProperty, value); }
        }
        public Int32 TradedDecimals
        {
            get { return (Int32)GetValue(TradedDecimalsProperty); }
            set { SetValue(TradedDecimalsProperty, value); }
        }
    }

[ValueConversion(typeof(object), typeof(BitmapImage))]
    public class SwapswireStatusImagePathConvertor : IMultiValueConverter
    {
        public String AllGoodPath { get; set; }
        public String InProgressPath { get; set; }
        public String WarningPath { get; set; }
        private DealObject _DealProp = null;
        public DealObject DealProp
        {
            get { return _DealProp; }
            set { _DealProp = value; }
        }

        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            String path = WarningPath;
            try
            {                
                if (null != DealProp && null != DealProp.Deal && null != values && values.Length == 2)
                {
                    String str1 = System.Convert.ToString(values[0]);
                    String str2 = System.Convert.ToString(values[1]);
                    if (DealProp.Deal.Swapswire)
                    {
                        switch (MBSConfirmationHelper.GetSwapswireStatus(str1, str2, MBSConfirmationHelper.GetParticipantType(DealProp.Deal)))
                        {
                            case DealExecutionStatus.InProgress:
                                path = InProgressPath; break;
                            case DealExecutionStatus.ActionRequired:
                            case DealExecutionStatus.Error:
                                path = WarningPath;
                                break;
                            case DealExecutionStatus.Executed:
                                path = AllGoodPath;
                                break;
                            case DealExecutionStatus.NotApplicable:
                                path = String.Empty;
                                break;
                        }
                    }
                    else path = String.Empty;
                }
            }
            catch (Exception)
            {

            }
            return String.IsNullOrEmpty(path)? null : new BitmapImage(new Uri(path, UriKind.Relative));
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException("Not Implemented");
        }
    }

in the above XAML code... I am trying to access datagrid's Tag property, the binding is working for the object is always comming null. How can I achieve this?

Upvotes: 1

Views: 725

Answers (1)

Vinit Sankhe
Vinit Sankhe

Reputation: 19895

The problem is evident from your code...

 <Control:SwapswireStatusImagePathConvertor.DealProp>
   <Control:DealObject 
         Deal="{Binding RelativeSource={RelativeSource FindAncestor, 
                        AncestorType={x:Type DataGrid}}, 
                        Path=Tag}"/>
 </Control:SwapswireStatusImagePathConvertor.DealProp>**

Your converter or any property within the converter can never be part of the visual tree and hence the binding wont work on it even if your deal object or the converter itself is a DependencyObject!

Please revise your binding ...

Why does your converter need to have a property that needs binding? You already have MultiBinding, so involve this binding as part of that ....

     <MultiBinding>
         <Binding Path="SwapswireBuyerStatusText"/>
         <Binding Path="SwapswireSellerStatusText"/>

         **<Binding RelativeSource="{RelativeSource FindAncestor, 
                  AncestorType={x:Type DataGrid}}"
                  Path="Tag"/>**

         <MultiBinding.Converter>
                <Control:SwapswireStatusImagePathConvertor 
                     AllGoodPath="/Resources/Done.png"
                     InProgressPath="/Resources/Go.png" 
                     WarningPath="/Resources/Warning.png" />
         </MultiBinding.Converter>
     </MultiBinding>

Now your converter receives all the 3 values that it needs ...

     String str1 = System.Convert.ToString(values[0]);
     String str2 = System.Convert.ToString(values[1]);
     ** this.DealProp = new DealObject();
     this.DealProp.Deal = values[2] as CMBSTrade; **

     if (DealProp.Deal.Swapswire) 
     {
           ....
     }

Let me know if this helps...

Upvotes: 1

Related Questions