Extending DataGrid columns
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2

Thread: Extending DataGrid columns

  1. #1
    Join Date
    May 2017
    Posts
    2

    Extending DataGrid columns

    I'm kind of new to WPF. I'm trying to write classes to extend DataGrid columns to make my life easier.

    Here's a sample mainwindow.xaml, containing two DataGrids. The one on top uses the new class, using the syntax that I want, but it doesn't work. The one on the bottom uses the old class, and it works, but the syntax is too complicated.

    Code:
    <UserControl x:Class="DataGridTestBed.MainWindow"
                 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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:local="clr-namespace:DataGridTestBed"
                 d:DataContext="{d:DesignInstance local:MainWindowViewModel, IsDesignTimeCreatable=True}"
                 mc:Ignorable="d">
        <StackPanel>
            <DataGrid
                ItemsSource="{Binding Items}"
                AutoGenerateColumns="False"
            >
                <DataGrid.Columns >
                    <local:TestDataGridTextColumn 
                        FieldConfig="{Binding FirstNameConfig}"
                        Binding="{Binding FirstName}"
                    />
                    <local:TestDataGridTextColumn 
                        FieldConfig="{Binding MiddleNameConfig}"
                        Binding="{Binding MiddleName}"
                    />
                    <local:TestDataGridTextColumn 
                        FieldConfig="{Binding LastNameConfig}"
                        Binding="{Binding LastName}"
                    />
                </DataGrid.Columns>
            </DataGrid>
    
    
            <DataGrid
                ItemsSource="{Binding Items}"
                AutoGenerateColumns="False"
            >
                <DataGrid.Resources>
                    <local:BindingProxy x:Key="Proxy" Data="{Binding}"/>
                </DataGrid.Resources>
                <DataGrid.Columns >
                    <DataGridTextColumn Binding="{Binding FirstName}" Header="{Binding Data.FirstNameHeader, Source={StaticResource Proxy}}" 
                                        Visibility="{Binding Data.FirstNameVisibility, Source={StaticResource Proxy}}"/>
                    <DataGridTextColumn Binding="{Binding MiddleName}" Header="{Binding Data.MiddleNameHeader, Source={StaticResource Proxy}}" 
                                        Visibility="{Binding Data.MiddleNameVisibility, Source={StaticResource Proxy}}"/>
                    <DataGridTextColumn Binding="{Binding LastName}" Header="{Binding Data.LastNameHeader, Source={StaticResource Proxy}}"
                                        Visibility="{Binding Data.LastNameVisibility, Source={StaticResource Proxy}}"/>
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </UserControl>
    The constructor for my main window view model:
    Code:
            public MainWindowViewModel()
            {
                FirstNameConfig = new FieldConfig { Header = "First Name", Visible = true };
                MiddleNameConfig = new FieldConfig { Header = "Middle Name", Visible = false };
                LastNameConfig = new FieldConfig { Header = "Last Name", Visible = true };
                Items = new ObservableCollection<TestItem>
                {
                    new TestItem() {FirstName = "Rocket", MiddleName = "J.", LastName="Squirrel"},
                    new TestItem() {FirstName = "Homer", MiddleName = "J.", LastName="Simpson"}
                };
            }
    TestDataGridTextColumn.xaml:
    Code:
    <DataGridTextColumn x:Class="DataGridTestBed.TestDataGridTextColumn"
                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                        Visibility="{Binding TheVisibility}"
                        Header="{Binding TheHeader}"
    >
    
    </DataGridTextColumn>
    TestDataGridTextColumn.xaml.cs:
    Code:
    using System.Windows;
    
    namespace DataGridTestBed
    {
        public partial class TestDataGridTextColumn
        {
    
            public static readonly DependencyProperty FieldConfigProperty = DependencyProperty.Register(
                "FieldConfig",
                typeof(FieldConfig), typeof(TestDataGridTextColumn));
    
            public FieldConfig FieldConfig
            {
                get { return GetValue(FieldConfigProperty) as FieldConfig; }
                set { SetValue(FieldConfigProperty, value); }
            }
    
            public Visibility TheVisibility => FieldConfig.Visibility;
            public string TheHeader => FieldConfig.Header;
    
            public TestDataGridTextColumn()
            {
                InitializeComponent();
            }
        }
    }
    These data errors are occurring:
    Code:
    System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=TheVisibility; DataItem=null; target element is 'TestDataGridTextColumn' (HashCode=28633162); target property is 'Visibility' (type 'Visibility')
    System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=TheHeader; DataItem=null; target element is 'TestDataGridTextColumn' (HashCode=28633162); target property is 'Header' (type 'Object')
    System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=FirstNameConfig; DataItem=null; target element is 'TestDataGridTextColumn' (HashCode=28633162); target property is 'FieldConfig' (type 'FieldConfig')
    And also, my "FieldConfig" setter isn't getting hit at all.

    How can I fix this, without overcomplicating the main window XAML? I'll extend the DataGrid class itself if I have to, but I really want to keep the main window XAML for the top DataGrid as close to the way it looks now as possible.

  2. #2
    Join Date
    May 2017
    Posts
    2

    Re: Extending DataGrid columns

    I updated the project in a major way, and it sort of works, but I'm not happy with it yet.

    My new main window:
    Code:
    <UserControl x:Class="DataGridTestBed.MainWindow"
                 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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                 xmlns:local="clr-namespace:DataGridTestBed"
                 d:DataContext="{d:DesignInstance local:MainWindowViewModel, IsDesignTimeCreatable=True}"
                 mc:Ignorable="d">
        <StackPanel>
            <local:TestDataGrid
                ItemsSource="{Binding Items}"
                AutoGenerateColumns="False"
            >
                <local:TestDataGrid.Columns >
                    <local:TestDataGridColumn 
                        FieldConfig="{Binding Data.FirstNameConfig, Source={StaticResource Proxy}}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding FirstName}"></TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </local:TestDataGridColumn >
    
                    <local:TestDataGridColumn 
                        FieldConfig="{Binding Data.MiddleNameConfig, Source={StaticResource Proxy}}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding MiddleName}"></TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </local:TestDataGridColumn >
    
                    <local:TestDataGridColumn 
                        FieldConfig="{Binding Data.LastNameConfig, Source={StaticResource Proxy}}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding LastName}"></TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </local:TestDataGridColumn >
                    
                </local:TestDataGrid.Columns>
            </local:TestDataGrid>
        </StackPanel>
    </UserControl>
    TestDataGridColumn.xaml:
    Code:
    <DataGridTemplateColumn x:Class="DataGridTestBed.TestDataGridColumn"
                        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    
    </DataGridTemplateColumn>
    TestDataGridColumn.xaml.cs:
    Code:
    using System.Windows;
    
    namespace DataGridTestBed
    {
        public partial class TestDataGridColumn
        {
    
            private FieldConfig _fieldConfig;
            private FieldConfig FieldConfigProperty
            {
                set
                {
                    _fieldConfig = value;
                    Header = _fieldConfig.Header;
                    Visibility = _fieldConfig.Visibility;
                }
            }
    
            public FieldConfig FieldConfig
            {
                get
                {
                    return (FieldConfig)GetValue(FieldConfigPropertyProperty);
                }
                set
                {
                    SetValue(FieldConfigPropertyProperty, value);
                }
            }
    
            public static readonly DependencyProperty FieldConfigPropertyProperty =
                DependencyProperty.Register("FieldConfig", typeof(FieldConfig), typeof(TestDataGridColumn), new UIPropertyMetadata(FieldConfigChangedHandler));
    
            public static void FieldConfigChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e)
            {
                ((TestDataGridColumn)sender).FieldConfigProperty = e.NewValue as FieldConfig;
            }
    
            public TestDataGridColumn()
            {
                InitializeComponent();
            }
        }
    }
    TestDataGrid.xaml:
    Code:
    <DataGrid x:Class="DataGridTestBed.TestDataGrid"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:DataGridTestBed"
                 mc:Ignorable="d" 
              >
        <DataGrid.Resources>
            <local:BindingProxy x:Key="Proxy" Data="{Binding}"/>
        </DataGrid.Resources>
    </DataGrid>
    But the main window xaml is way more complicated than I want it to be. Where it says this -
    Code:
                    <local:TestDataGridColumn 
                        FieldConfig="{Binding Data.FirstNameConfig, Source={StaticResource Proxy}}">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding FirstName}"></TextBlock>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </local:TestDataGridColumn >
    ...I just want it to look like this..
    Code:
                    <local:TestDataGridColumn 
                        FieldConfig="{Binding FirstNameConfig}"
                        Binding="{Binding FirstName}"/>
    ... and do the same thing.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This a Codeguru.com survey!


On-Demand Webinars (sponsored)