views:

321

answers:

1

Hello! I have such task - to create control that union two controls (DataGrid from WPFToolkit and standard Toolbar). On a large scale, it doesn't matter what particular controls it unions, I need to find out the common practices that can be used to build what I need. At first glance, I need something like user control, i.e composition of controls, that I can implement as a whole and reuse then. But, my task requires me to have possibility to tune my composite control in XAML. So, if I compose Toolbar and DataGrid, I want properties and events of both them would be exposed. So I could set in XAML both, for example, columns of datagrid and bars of toolbar:

(I put spaces in tag names intentionally, because loacal parser didn't type them for some reason)

<MyDataGridToolBarControl>
<DataGrid>
        <DataGrid.Columns>
            <DataGridTextColumn Header="firstColumn">
            </DataGridTextColumn>
            <DataGridTextColumn Header="secondColumn"/>
        </DataGrid.Columns>
</DataGrid>
<ToolBar Background="{x:Null}"> 
        <Button ToolTip="New">
            <Image Source="New.png"/>
        </Button>
        <Button ToolTip="Save">
            <Image Source="Save.png"/>
        </Button>
        <Button ToolTip="Delete">
            <Image Source="Delete.png"/>
        </Button>               
</ToolBar>
</MyDataGridToolBarControl>

The only decison that suits me less or mor for now is to make custom control inherited from Datarid (as DataGrid is more significant in this pair) and redefine Template including both datagrid and toolbar. This gives me all power of datagrid but, if I want get Toolbar part, I need to do it through code, seeking it in viual and logical trees i.e. getting access o it programmatcally, which is not pretty decision. Please help a newbie to solve this task ) Thanks in advance...

+1  A: 

If it's just a matter of wanting users on the outside to access every property of the grid and every property of the toolbar via Xaml then using composition you could create a usercontrol and expose the two controls like this:

<UserControl>

    <StackPanel>
        <ToolBar x:Name="ToolBar" x:FieldModifier="Public" />
        <DataGrid x:Name="Grid" x:FieldModifier="Public" />         
    </StackPanel>

<UserControl>

The problem with this approach is that that users cannot override the layout of the grid and toolbar because it is a user control. They can however completely override the templates and styles of the toolbar and the grid.

A slightly better approach would be to create a custom control (again using composition). You could supply could the grid and the toolbar in the template like this:

<ControlTemplate>
        <StackPanel>
            <ToolBar x:Name="PART_ToolBar" />
            <DataGrid x:Name="PART_Grid" />         
        </StackPanel>
</ControlTemplate>

[TemplatePart("PART_ToolBar", typeof(ToolBar))]
[TemplatePart("PART_Grid", typeof(DataGrid))]
public class MyCustomControl : Control
{
    private ToolBar _ToolBar;
    public ToolBar ToolBar {get{return _ToolBar;}}

    private DataGrid _Grid;
    public DataGrid Grid {get{return _Grid;}}

    protected overrides OnApplyTemplate()
    {
         _ToolBar = this.Template.FindName("PART_ToolBar", this) as ToolBar;
         _Grid = this.Template.FindName("PART_Grid", this) as DataGrid;
    }
}
Micah
Thank You for your answer, I'm trying to implement this approach now, and while I'm doing it - tell me please: what about events? Is it possible to handle native toolbar and grid evensts with this approach?
Andrey Khataev
As long as the Grid or the ToolBar are exposed to the outside (which they are in both cases) You can do everything you want to them as if you instantiated them directly. Of course this breaks encapsulation and could cause issues down the road if the consumers do something screwy to the control
Micah
May I send You via e-mail my sample project with such datagrid implemented in both ways and You show me how to define inner Toolbar's and DataGrid's properties using custom xaml styles? Would You be so glad?I did as You've said but inner elements exposed as properties are not visible in XAML
Andrey Khataev
sure thing. You can send me an email to micah at codingcontext.com
Micah
Hello, Micah! Have You got my e-mail with samples?
Andrey Khataev
No I never got it.
Micah
I've re sent letter. Please check Your e-mail box. May be it is being sorted as junk/spam for some reason?
Andrey Khataev
yeah It's coming through and getting flagged as containing a virus. Try sending me an email without the attachment and we'll go from there.
Micah
There cannoot be a virus. First, I have NOD32 antivirus installed. Second, I again resend You solution, where I have excluded all dlls and binaries, that could be infected. There are only source codes left. I think it is acceptable choice for us both,cause it is too difficult post sources pure email
Andrey Khataev
Micah, where have you gone, I don't get any response from You by e-mail...
Andrey Khataev