private void UpdateHeaderProperty(
            GridViewColumnHeader header,    // the header need to update
            DependencyProperty targetDP,    // the target DP on header
            DependencyProperty columnDP,    // the DP on Column as 1st source, can be Null
            DependencyProperty gvDP         // the DP on GridView as 2nd source
            )
        {
            if (gvDP == ColumnHeaderContainerStyleProperty
                && header.Role == GridViewColumnHeaderRole.Padding)
            {
                // Because padding header has no chance to be instantiated by a sub-classed GridViewColumnHeader,
                // we ignore GridView.ColumnHeaderContainerStyle silently if its TargetType is not GridViewColumnHeader (or parent)
                // I.e. for padding header, only accept the GridViewColumnHeader as TargetType
                Style style = ColumnHeaderContainerStyle;
                if (style != null && !style.TargetType.IsAssignableFrom(typeof(GridViewColumnHeader)))
                {
                    // use default style for padding header in this case
                    header.Style = null;
                    return;
                }
            }

            GridViewColumn column = header.Column;

            object value = null;

            if (column != null /* not the padding one */
                && columnDP != null /* Column doesn't has ContextMenu property*/)
            {
                value = column.GetValue(columnDP);
            }

            if (value == null)
            {
                value = this.GetValue(gvDP);
            }

            header.UpdateProperty(targetDP, value);
        }