DataGrid binding not working in GroupItem style declaration

2.2k views Asked by At

I'm having some trouble getting a binding to work that is defined in the resouces section of my user control. The same binding seems to work later on in the xaml when I bind it to a column of the datagrid. It just won't display data when in the style declaration.

The error I get is

System.Windows.Data Error: 40 : BindingExpression path error: 'ReceivedDate' property not found on 'object' ''CollectionViewGroupInternal' (HashCode=5477078)'. BindingExpression:Path=ReceivedDate; DataItem='CollectionViewGroupInternal' (HashCode=5477078); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

The below binding ReceivedDate is not resolving at runtime.

<UserControl.Resources>

    <!-- Grouped Items Header: Show the messages in a group. ex: date received -->
    <Style x:Key="GroupedItemsHeaderStyle" TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type GroupItem}">
                    <Expander x:Name="exp" IsExpanded="True"
                              Background="LightGray"
                              Foreground="Black">
                        <Expander.Header>
                            <TextBlock Text="{Binding Path=ReceivedDate, Converter={StaticResource DateToSortGroupConverter}}" Foreground="Black"/>
                        </Expander.Header>
                        <ItemsPresenter/>
                    </Expander>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

</UserControl.Resources>

In the code-behind for this UserControl I'm setting the itemsList as follows.

    void MailController_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "CurrentMailBoxContent")
        {
            var currentMailBox = ((App) Application.Current).MailController.CurrentMailBoxContent;
            var collection = new ListCollectionView(currentMailBox);

            collection.GroupDescriptions.Add(new PropertyGroupDescription("ReceivedDate"));
            ContentDataGrid.ItemsSource = collection;
        }
    }

CurrentMailBoxContent is an

ObservableCollection<MailMessage>;

and ReceivedDate is a property in the MailMessage class.

public class MailMessage : INotifyPropertyChanged
{
    #region Fields

    public event PropertyChangedEventHandler PropertyChanged;

    private DateTime _receivedDate;

    #endregion

    #region Constructor

    public MailMessage(){}

    #endregion

    #region Properties


    public DateTime ReceivedDate
    {
        get { return _receivedDate; }
        set
        {
            if (_receivedDate == value) return;
            _receivedDate = value;
            OnPropertyChanged("ReceivedDate");
        }
    }

    #endregion

    #region methods

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

I've tried changing the path of the binding to /ReceivedDate.

The thing that confuses me is that the same binding works when declared elsewhere. Such as in the various column headers.

1

There are 1 answers

4
gomi42 On BEST ANSWER

The Expander.Header does not get one of your view models. Instead the header gets an object that inherits from CollectionViewGroup that has two properties named Name and ItemCount.