This is a migrated thread and some comments may be shown as answers.

DragDropMode=-Deferred DragVisual Template and offset

8 Answers 54 Views
Docking
This is a migrated thread and some comments may be shown as answers.
Dean Wyant
Top achievements
Rank 1
Dean Wyant asked on 26 Feb 2016, 06:01 PM

What is the recommended way to set the DragVisual to a template for Deferred drag and drop?
I would also like to change the DragVisual offset for all deferred drags of a Title Bar so that it is X centered at the cursor even if the drag click was on the right side of the Title Bar (the tab drag offset is fine the way it is).

It looks like there are two DragVisuals - one for RadPane and one for RadPaneHeader. 

I have set my title and header templates to a template that only includes an image (icon). 

   Pane.TitleTemplate = myTemplate;       
   Pane.HeaderTemplate = myTemplate;

When dragging, the DragVisual / indicator is empty because it is not using my template, it is getting a string for the Title. 
I would like it to use the same template. 

I have not found a way to accomplish this.

I have tried DragDropManager.AddDragInitializeHandler(PaneGroup, OnDragInitialize); but it does not call my handler. Even if it did, there are issues with the RadPaneHeader not being exposed to allow me to call AddDragInitializeHandler(PaneHeader, OnDragInitialize).

I see that the OnDragInitialize methods are virtual. I considered creating classes to override them, but the LoadLayout / XML layout loader requires the classes to be named "RadPane". Also, I probably could not get the classes to use MyRadPaneHeader. 

I am compiling source, so changing the code is a viable option for me. Of course, a reliable method that does not require code changes would be OK too. 

If code changes are the easiest method,  having the code look for a HeaderTemplate or TitleTemplate (accordingly) and use it if found would be great. If not found, the current code could be used. Those code changes sound like something everyone would want - it seems logical to use the provided template instead of just a string.

If code changes are the way to go, some help on what code changes to make in RadPane and RadPaneHeader.OnDragInitialize would be greatly appreciated.  

Thank You,

Dean

 

 

 

 

8 Answers, 1 is accepted

Sort by
0
Nasko
Telerik team
answered on 02 Mar 2016, 08:54 AM
Hello Dean,

In order to achieve the desired appearance for the DragVisual you just need to modify the default Style of the DraggedElementVisualCue of RadDocking. By modifying the ControlTemplate with Key DraggedElementVisualCueTemplate the desired could be achieved.

We have created a sample project that demonstrates that approach - please, notice that Implicit Styles are used. 

Hope this helps.

Regards,
Nasko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dean Wyant
Top achievements
Rank 1
answered on 02 Mar 2016, 03:53 PM
Thank You for the example project.
Unfortunately, I do not understand how to modify the example to duplicate the RadPane Header contents.

I see that the example globally sets the visual by binding to the property RadPane.Title so that each visual is different.
I do not see how I can modify it to show the same content as the RadPane.HeaderTemplate – which can be different for every RadPane.
I tried replacing the TextBlock with a ContentControl and setting its ContentTemplate to bind to the RadPane.HeaderTemplate. However, I cannot get the binding to work. Even if I could, the binding inside of the RadPane.HeaderTemplate for Text is currently = {Binding} which will not work inside of the visual (see below).  

The header templates include images (icons) that are not properties that can be bound to.
Examples:      
<DataTemplate x:Key="DockingHeaderTemplateGrid">
  <StackPanel Orientation="Horizontal">
    <Image Source="../Images/Grid.png" />
    <TextBlock Text="{Binding}"/>
  </StackPanel>
</DataTemplate>
<DataTemplate x:Key="DockingHeaderTemplateChart">
  <StackPanel Orientation="Horizontal">
    <Image Source="../Images/Chart.png" />
    <TextBlock Text="{Binding}"/>
  </StackPanel>
</DataTemplate>
<DataTemplate x:Key="DockingHeaderTemplateOther">
  <StackPanel Orientation="Horizontal">
    <Image Source="../Images/Other.png" />
    <TextBlock Text="{Binding}"/>
    <Image Source="../Images/Additional.png" />
  </StackPanel>
</DataTemplate>

So, each RadPane header template is always set (to a template similar to the above templates).
HeaderTemplate="{StaticResource DockingHeaderTemplateGrid}"

Actually, I set them in code based on the type of pane being created.

Is there a solution that will allow the visual to have the same contents the RadPane.Header/HeaderTemplate has?
Perhaps another set of templates, an attached property, etc. is required?

Thank You
0
Accepted
Kalin
Telerik team
answered on 03 Mar 2016, 01:29 PM
Hello Dean,

The desired can be achieved if use a custom object as a Header. The object should have two properties - one containing the text for the header and one with the image path. For example:

public class HeaderObject
{
    public string Header { get; set; }
    public string ImagePath { get; set; }
}

This way you could bind the properties in the Header and Title Templates as shown below:
<telerik:RadPane>
    <telerik:RadPane.Header>
        <local:HeaderObject Header="ToolBox" ImagePath="../Images/today.png" />
    </telerik:RadPane.Header>
    <telerik:RadPane.HeaderTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Image Source="{Binding ImagePath}" />
                <TextBlock Text="{Binding Header}"/>
            </StackPanel>
        </DataTemplate>
    </telerik:RadPane.HeaderTemplate>
    <telerik:RadPane.TitleTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Header}"/>
        </DataTemplate>
    </telerik:RadPane.TitleTemplate>
</telerik:RadPane>

And afterwards bind the DraggedElementVisualCue ControlTemplate as demonstrated below:
<ControlTemplate x:Key="DraggedElementVisualCueTemplate">
    <Grid>
        <Border
        Margin="0 0 4 4"
        CornerRadius="1"
        BorderBrush="{TemplateBinding BorderBrush}"
        BorderThickness="{TemplateBinding BorderThickness}"
        Background="{TemplateBinding Background}"/>
        <Border Margin="0 0 4 4" Padding="{TemplateBinding BorderThickness}">
            <StackPanel Orientation="Horizontal" Margin="3">
                <Image Source="{Binding Title.ImagePath}" />
                <TextBlock Text="{Binding Title.Header}"/>
            </StackPanel>
        </Border>
    </Grid>
</ControlTemplate>

I have also attached and the modified project.

Hope this will help you.

Regards,
Kalin
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dean Wyant
Top achievements
Rank 1
answered on 04 Mar 2016, 04:01 PM

I see now... the DockingDragDropPayload is the DataContext and public object Payload.Title = Pane.Header. 
Thank You

Setting Pane.Header to a HeaderObject causes SaveLayout / LoadLayout to set the Pane.Header xml to the Type name (...HeaderObject). 

What is the best way to serialize / deserialize the new HeaderObject for SaveLayout / LoadLayout? 

 

0
Dean Wyant
Top achievements
Rank 1
answered on 07 Mar 2016, 08:50 PM

Some hints on the recommended way to approach saving / loading the HeaderObject (SaveLayout/LoadLayout) would be very helpful. I do not need an example app.

Thanks. 

0
Nasko
Telerik team
answered on 08 Mar 2016, 07:30 AM
Hello Dean,

What we could suggest you is to handle the ElementSaving event and inside it to preserve the "HeaderObject" of the Pane that is currently saving. You need also to handle the ElementLoaded event. When you load the Pane based on its AffectedElementSerializationTag you could set the preserved in the ElementSaving event Header - thus the header should be visualized as expected. 

Notice that with Q2 2016 we will introduce the functionality  to change the default save/load layout mechanism of RadDocking that is now available and the desired will be much easier achieved.

Attached you could find a sample project that demonstrates the described above approach.

I hope this will help you.

Regards,
Nasko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dean Wyant
Top achievements
Rank 1
answered on 08 Mar 2016, 03:49 PM

Using a member to "preserve" the HeaderObject does not seem to be helpful since the layout would need to be loaded on app startup.

I guess I did not miss any events etc. that would make adding the XML for serialization/deserialization any easier.
I know I can use the SerializationTag, but I found a more generic approach.

Since the Header content in XML was not useful (just the type name), I went ahead and used it for the HeaderObject serialized XML. 
I found that the XML Header content is obtained from ToString or IFormattable.ToString.

I made HeaderObject : IFormattable and implemented IFormattable.ToString to return the HeaderObject XML.
Then, during the ElementLoaded event handling, the Header content (String or XML) is handled. 

I coded it so that the Pane.Header can be a String or any Object that implements IFormattable.ToString to return XML. Layout.xml Header content will be the string or the object's XML. On ElementLoaded, if it is XML, Pane.Header = DeserializedObject.

If I want to have different header objects, I can create other classes with IFormattable.ToString that returns XML. Of course, I would also need other templates to match. 

Thanks

 

191818882299Thanks.
0
Nasko
Telerik team
answered on 09 Mar 2016, 08:35 AM
Hi Dean,

Thank you for sharing with us your solution it is a really nice one. As I mentioned in my previous response with Q2 2016 we will provide the functionality to change the currently built-in functionality for save/load layout of RadDocking - we will provide an easy way to save any desired property and its value to the generated XML file and you will be able to achieve the desired much easier.

As soon as Q2 2016 gets released you could try give it a try.

If you have any additional questions or concerns regarding Telerik controls, please do not hesitate to contact us.

Regards,
Nasko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Docking
Asked by
Dean Wyant
Top achievements
Rank 1
Answers by
Nasko
Telerik team
Dean Wyant
Top achievements
Rank 1
Kalin
Telerik team
Share this question
or