none
Problems when binding inherited DataGridTextColumn properties - visibility and header.

    Question



  • Hello,

    I have faced an other problem when doing MVVM based Silverlight development. I hope someone could help.

    I have ViewModel that contains dynamical data got from db and I want to vizualise it on my view that is DataTemplate containing one DataGrid. Debending on the data the number of columns and column headers may vary. I have found out that SL datagridcolumn does not support binding of Header / Visibility. I solved this by creating an inherited class of datagridtextcolumn and adding there two DependencyProperties.

    My viewmodel works fine, because if I bind the Header1 to any label, it gets the new value whenever it is changed. ALSO, the getter of the ListObjects collection is called and all the items in the collection are shown in the grid. The headers are NOT. When the binding is done in my inherited datagridtextcolumn the getter of my Header1 (in my vm) is never actually called.

    Here are the snippets of my code:

    # View - XAML #
       

    <data:DataGrid HorizontalAlignment="Stretch" Margin="5" MinWidth="500" Width="auto"  Grid.Column="1"  ItemsSource="{Binding ListObjects}"  >
            <data:DataGrid.RowGroupHeaderStyles >
                <Style BasedOn="{StaticResource DataGridRowGroupBottomWhite}" TargetType="data:DataGridRowGroupHeader" />
            </data:DataGrid.RowGroupHeaderStyles>
    
            <data:DataGrid.Columns >
                <data:DataGridTextColumn Binding="{Binding group}" Visibility="Collapsed" />
                <sa:ExtendedDataGridTextColumn Binding="{Binding Value1}" IsVisible="{Binding Header1, Converter={StaticResource stovconverter}}" ColumnHeader="{Binding Header1}" />
            </data:DataGrid.Columns>
        </data:DataGrid>



    Converter is never called, but if it were, it would check if the Header is null or empty and return True/False.


    # ExtendedDataGridTextColumn #

    public class ExtendedDataGridTextColumn : DataGridTextColumn
        {
            public ExtendedDataGridTextColumn()
                : base()
            {
            }
    
            public bool IsVisible
            {
                get
                {
                    return (bool)GetValue(IsVisibleProperty);
                }
                set
                {
                    SetValue(IsVisibleProperty, value);
                }
            }
            public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.Register("IsVisible",
                typeof(bool),
                typeof(ExtendedDataGridTextColumn),
                new PropertyMetadata(HideColumnChanged)
                );
    
            private static void HideColumnChanged(object sender, DependencyPropertyChangedEventArgs args)
            {
                DataGridTextColumn dgc = sender as DataGridTextColumn;
                
                bool v = (bool)args.NewValue;
                if (args.NewValue != args.OldValue)
                {
                    if (v)
                    {
                        dgc.Visibility = Visibility.Visible;
                    }
                    else
                    {
                        dgc.Visibility = Visibility.Collapsed;
                    }
                }
            }
    
    
            public string ColumnHeader
            {
                get
                {
                    return (string)GetValue(ColumnHeaderProperty);
                }
                set
                {
                    SetValue(ColumnHeaderProperty, value);
                }
            }
    
            public static readonly DependencyProperty ColumnHeaderProperty = DependencyProperty.Register("ColumnHeader",
            typeof(string),
            typeof(ExtendedDataGridTextColumn),
            new PropertyMetadata(ColumnHeaderChanged)
            );
    
            private static void ColumnHeaderChanged(object sender, DependencyPropertyChangedEventArgs args)
            {
                DataGridTextColumn dgc = sender as DataGridTextColumn;
    
                string h = (string)args.NewValue;
                if (args.NewValue != args.OldValue)
                {
                    dgc.Header = h;
                }
            }
        }




    # ViewModel - C# #

    namespace SilverlightApplication1.ViewModels
    {
        public class ListViewModel : INotifyPropertyChanged
        {
            public struct ListObject
            {
    
                public object group { get; set; }
                public object Value1 { get; set; }
    
            }
            
            public PagedCollectionView ListObjects
            {
                get { return _pagedlist; }
                set
                {
                    _pagedlist = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("ListObjects"));
                    }
                }
             }
            
            public string Header1
            {
                get { return _Header1; }
                set
                {
                    _Header1 = value;
                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("Header1"));
                    }
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;
        }
    
    }





    The solution may be very simple, however, I am not able to notice it. Thanks for help in advance!

    Br,
    Antti

    Friday, July 23, 2010 9:15 AM

Answers

  • Hi,

       One thing I want to say is that. When you assign value in the callback of your DP's property changed event.

       The oneway binding will be break.

       I suspect this is the cause of your problem.

       You may try use twoway. Or not assign value in the callback at all.

    Best Regards 

    Monday, July 26, 2010 2:42 AM