Question

Is it possible to base one or more controls on a control that is defined in the Resources. So that the controls inherit most properties from the base control. Similar to the Style approach but for some reason I cannot use Events/EventSetter (AutoGeneratingColumns in this case), the error I get is "xy-Event is not a Routed Event"

Here an example of what I want to accomplish. I have datagrids where most of the properties are the same

<DataGrid x:Name="gridEditSystem"
           AutoGeneratingColumn="onGridEditSystem_autoGeneratingColumn"
           SelectionUnit="Cell"
           SelectionMode="Single" CellStyle="{StaticResource GridEditStyle}">
</DataGrid>

<DataGrid x:Name="gridEditPlanets" SelectedCellsChanged="gridEditPlanets_SelectedCellsChanged"
           AutoGeneratingColumn="onGridEditSystem_autoGeneratingColumn"
           SelectionUnit="Cell"
           SelectionMode="Single" CellStyle="{StaticResource GridEditStyle}">
</DataGrid>

What I want now is a "Base Control"

<Window.Resources>
    <DataGrid x:Key="BaseDataGrid" AutoGeneratingColumn="onGridEditSystem_autoGeneratingColumn"
              SelectionMode="Single" SelectionUnit="Cell"
              CellStyle="{StaticResource GridEditStyle}">
    </DataGrid>
</Window.Resources>

And inheriting Controls

 <DataGrid x:Name="gridEditSystem"
           BasedOn/Inherits/Templates={StaticResource BaseDataGrid}
 </DataGrid>

 <DataGrid x:Name="gridEditPlanets" 
           BasedOn/Inherits/Templates={StaticResource BaseDataGrid}
 </DataGrid>

I tried a few combinations but failed so far nor did I find anything on Google. Is this possible in XAML?

Was it helpful?

Solution

You cannot do that, However in WPF you can approch this in many ways.

You can make a custom grid control with all your common properties, and use it instead of the regular DataGrid control.

    public class BaseDataGrid : DataGrid
    {
        protected override void OnInitialized(EventArgs e)
        { 
             base.OnInitialized(e);

             // Set all you common properties here
             SelectionUnit = DataGridSelectionUnit.Cell;
             SelectionMode = DataGridSelectionMode.Single;
             CellStyle = FindResource("GridEditStyle") as Style;
         }
    }

in your xaml

        <local:BaseDataGrid x:Name="gridEditSystem"/>
        <local:BaseDataGrid x:Name="gridEditPlanets"/>

You can also make a behavoir with all your common properties and attach it to the DataGrids you want.

     public class BaseGridBehavior : Behavior<DataGrid>
     {
        protected override void OnAttached()
        {
            AssociatedObject.Initialized += AssociatedObject_Initialized;

             base.OnAttached();
        }

        void AssociatedObject_Initialized(object sender, EventArgs e)
        {
            // Set all you common properties here
            AssociatedObject.SelectionUnit = DataGridSelectionUnit.Cell;
            AssociatedObject.SelectionMode = DataGridSelectionMode.Single;
            AssociatedObject.CellStyle = AssociatedObject.FindResource("GridEditStyle") as Style;
        }
    }

and in xaml:

        <DataGrid x:Name="gridEditSystem">
            <i:Interaction.Behaviors>
                <local:BaseGridBehavior/>
            </i:Interaction.Behaviors>
        </DataGrid>
        <DataGrid x:Name="gridEditPlanets">
            <i:Interaction.Behaviors>
                <local:BaseGridBehavior/>
            </i:Interaction.Behaviors>
        </DataGrid>

This will need you to include and reference the System.Windows.Interactivity dll

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top