0

I have an application that uses two separate projects. One is for the main executable which contains my ViewModels and the other is to control the theme/style of the application.

In the theme project, I have customized the DataGridColumnHeader's Style to include a CheckBox. Now how do I databind the CheckBoxes to my ViewModel?

My theme xaml

<Style x:Key='PlottableFilteringColumnHeaderStyle' TargetType='{x:Type primitives:DataGridColumnHeader}'>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type primitives:DataGridColumnHeader}">
                <Grid>
                    <themes:DataGridHeaderBorder x:Name='HeaderBorder'>
                        <Grid x:Name="GridColumnHeader">
                            <StackPanel x:Name="argStackPanel">
                                <CheckBox x:Name="argCheckBox" Content="Enable Arg" Style="{DynamicResource ResourceKey=DefaultCheckBox}" />
                            </StackPanel>
                        </Grid> 
                    </themes:DataGridHeaderBorder>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I am then using MultiBinding for the argCheckBox

public class HeaderArgConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string headerText = values[0] as string;

        if (!String.IsNullOrWhiteSpace(headerText))
        {
            FrameworkElement targetElement = values[1] as FrameworkElement;
            DataGridColumnHeader header = targetElement.TemplatedParent as DataGridColumnHeader;
            string columnName = header.DataContext != null ? header.DataContext.ToString() : "";
            var argNumber = System.Text.RegularExpressions.Regex.Match(columnName.Split(':')[0], @"\d+$").Value; // use the header text to determine which arg number

            Binding binding = new Binding("SelectedViewModel.EnableArg" + argNumber);
            binding.Source = Window.DataContextProperty;  // This is what I am unsure about
            (targetElement as CheckBox).SetBinding(CheckBox.IsCheckedProperty, binding);
        }
    }
}

I keep getting 'BindingExpression path error: property not found on 'object'' error. Any ideas on how to fix this or if there is a better way to do this?

Mpressiv
  • 48
  • 5
  • 1
    This is going to be problematic because you effectively need to create a new dependency property for the `checked` property that you want to bind, and although you're creating a template you're setting it in a style, at which point you lose any properties that aren't inherent to the type that you're trying to bind. Basically you have 2 options: 1) create a custom DataGridColumnHeader that contains the msising DP, or 2) create view models for your columns and [dynamically bind to them](http://stackoverflow.com/questions/320089/how-do-i-bind-a-wpf-datagrid-to-a-variable-number-of-columns). – Mark Feldman Mar 01 '16 at 06:06
  • Actually a third solution would involve adding an attached behaviour which uses attached properties for the binding, but that's really just moving the code from code behind into a behaviour. I'd probably go down the route of dynamic column binding myself. – Mark Feldman Mar 01 '16 at 06:09
  • 1
    go for 1) create a custom DataGridColumnHeader that contains the missing DP – blindmeis Mar 01 '16 at 09:37
  • Thanks Mark for the explanation. I have my datagrid rows already binded to view models. I will try your first suggestion. – Mpressiv Mar 01 '16 at 19:59
  • Could you please provide an example on how I would connect the newly created dependency property to my main executable project? – Mpressiv Mar 02 '16 at 18:38

0 Answers0