0

I want to use an attached property with a DataGridColumn for the sake of determining what data each row should display based on that columns value.

In compliance with the Minimal, Complete and Verifiable Example requirements:

App.Xaml.CS:

using System;
using System.Diagnostics;
using System.Globalization;
using System.Windows;

namespace MCVE {
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
    public partial class App {
        private static readonly CultureInfo[] _languages;
        public static readonly DependencyProperty SelectedLanguageProperty;

        static App( ) {
            _languages = CultureInfo.GetCultures( CultureTypes.AllCultures );
            SelectedLanguageProperty = DependencyProperty.RegisterAttached(
                "SelectedLanguage", typeof( CultureInfo ), typeof( App ),
                new PropertyMetadata( new CultureInfo( "en-US" ), _SelectedLanguageChanged ) );

            void _SelectedLanguageChanged( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
                //For examining sender.
            }
        }

        public static CultureInfo[] Languages => _languages;

        public static CultureInfo GetSelectedLanguage( DependencyObject source ) =>
            source.GetValue( SelectedLanguageProperty ) as CultureInfo;

        public static void SetSelectedLanguage( DependencyObject target, CultureInfo value ) =>
            target.SetValue( SelectedLanguageProperty, value );

        [STAThread]
        public static void Main( ) {
            App program = new App( );
            program.InitializeComponent( );
            program.Run( );
        }
    }
}

MainWindow.xaml:

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:l="clr-namespace:MCVE"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    x:Class="MCVE.MainWindow"
    mc:Ignorable="d" Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <DataTemplate x:Key="ColumnHeader">
        <ComboBox
            DisplayMemberPath="DisplayName"
            ItemsSource="{Binding Source={x:Static l:App.Languages}}"
            SelectedItem="{Binding 
                Mode=TwoWay, Path=(l:App.SelectedLanguage),
                RelativeSource={RelativeSource TemplatedParent}}"/>
        </DataTemplate>
    </Window.Resources>
    <DataGrid Background="{x:Null}">
        <DataGrid.Columns>
            <DataGridTextColumn
                HeaderTemplate="{StaticResource ColumnHeader}">
                <DataGridTextColumn.HeaderStyle>
                    <Style TargetType="{x:Type DataGridColumnHeader}">
                        <Setter Property="HorizontalContentAlignment" Value="Stretch" />
                    </Style>
                </DataGridTextColumn.HeaderStyle>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Window>

The result is that the method which fires shows that the DependencyObject source is a ContentPresenter whose parent is NOT the DataGridColumn of the header in which the template is defined.

How can I go about associating this attached property with the header of the column and access it from the data grids rows?

Will
  • 3,413
  • 7
  • 50
  • 107
  • A column is an abstract thing. There isn't a column in a datagrid. if you don't have it already, install snoop. Spin your app up. Run snoop. Take a look at what's in a datagrid. There is a header hanging about there and there are cells in rows but they're not in a column which maps to your datagridtextcolumn. You can't just work up the visual tree from a cell and get it's header. What end result do you wish to achieve? Because you probably need a different plan. – Andy Apr 21 '18 at 08:58
  • @Andy The end goal would be to change what the text column displays in each row based on the value contained within the combo box contained within the column header. The underlying data source contains different languages, each serving as a "Key" to determine what the text box should display. – Will Apr 21 '18 at 13:41
  • If the combo is defined in a resource like that it's inheriting the windows's datacontect ( viewmodel ). You can just bind to a property on the viewmodel. Use change of that to drive some processing that manipulates data in the child viewmodels property which is bound to that column. – Andy Apr 21 '18 at 13:52

0 Answers0