DragDropMode=-Deferred DragVisual Template and offset

9 posts, 1 answers
  1. Dean Wyant
    Dean Wyant avatar
    46 posts
    Member since:
    Nov 2009

    Posted 26 Feb Link to this post

    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

     

     

     

     

  2. Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 02 Mar Link to this post

    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
  3. DevCraft banner
  4. Dean Wyant
    Dean Wyant avatar
    46 posts
    Member since:
    Nov 2009

    Posted 02 Mar in reply to Nasko Link to this post

    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
  5. Answer
    Kalin
    Admin
    Kalin avatar
    1207 posts

    Posted 03 Mar Link to this post

    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
  6. Dean Wyant
    Dean Wyant avatar
    46 posts
    Member since:
    Nov 2009

    Posted 04 Mar in reply to Kalin Link to this post

    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? 

     

  7. Dean Wyant
    Dean Wyant avatar
    46 posts
    Member since:
    Nov 2009

    Posted 07 Mar in reply to Kalin Link to this post

    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. 

  8. Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 08 Mar Link to this post

    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
  9. Dean Wyant
    Dean Wyant avatar
    46 posts
    Member since:
    Nov 2009

    Posted 08 Mar Link to this post

    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.
  10. Nasko
    Admin
    Nasko avatar
    585 posts

    Posted 09 Mar Link to this post

    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
Back to Top
DevCraft banner