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

How to enable default commands (without focus)

7 Answers 206 Views
ImageEditor
This is a migrated thread and some comments may be shown as answers.
Brian
Top achievements
Rank 1
Brian asked on 29 Oct 2018, 10:49 AM

Hi,

I have a RadImageEditor that I am using as an image viewer, and I have added my own toolbar with buttons bound to the commands for rotating and flipping the image, which all works fine. 

However, the buttons remain disabled until I click on the image, but I would really like the user to be able to just click on one of the buttons without having to first click on the image.  Equally, if they click on the zoom control, this gets the focus and the buttons once again get disabled.

How can I permanently enable these buttons?

Thanks,

Brian

7 Answers, 1 is accepted

Sort by
0
Brian
Top achievements
Rank 1
answered on 29 Oct 2018, 12:43 PM

I have got around this by implementing my own commands and executing code like the following (for horizontal flip in this case):

                FlipCommandContext context = new FlipCommandContext(Orientation.Horizontal);
                _currEditor.ExecuteCommand(new FlipCommand(), context);

This works OK, but I did read on some other thread that was using similar code that it lead to out of memory errors after a while.  Can someone tell me if this code is OK, or am I creating multiple copies of the image each time I execute it?

Thanks

0
Martin Ivanov
Telerik team
answered on 31 Oct 2018, 12:15 PM
Hello Brian,

To use the image editor commands outside of the RadImageEditorUI you can bind the Command property of the corresponding button to a command from the Commands property of the RadImageEditor control. Here is an example in code:
<Grid>
    <StackPanel Orientation="Horizontal">
        <Button Content="Open file" Command="{Binding ElementName=imageEditor, Path=Commands.Open}"/>
        <Button Content="Flip Horizontal" Command="{Binding ElementName=imageEditor, Path=Commands.FlipHorizontal}"/>
    </StackPanel>
    <telerik:RadImageEditor x:Name="imageEditor" Background="LightGray" Margin="10"/>
</Grid>

The approach you are currently, using is also fine. As for the memory issue, this is not related to the commands. You will get the same issue also if you use the commands bound in the RadImageEditorUI. It comes from the nature of the history (the undo/redo stack) implementation of the control. Basically, each time you execute a command that changes the image, the current instance of the image is stored in the stack, and a new instance with the changes is created. This way you have the whole picture stored many times and at some point the application grows very big in memory. To avoid this you can remove items from the history stack from time to time. Here is an example in code:
rivate void ImageEditor_ToolCommitted(object sender, Telerik.Windows.Media.Imaging.Tools.ToolCommittedEventArgs e)
{
    long memory = GC.GetTotalMemory(true);
    if (memory == 200000000)
    {
        var history = this.ImageEditorUI.ImageEditor.History;
        history.Clear();
    
}

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Brian
Top achievements
Rank 1
answered on 31 Oct 2018, 12:51 PM

Hi Martin,

That's just what I was looking for. :)

I'm using the RadImageEditor as a viewer, but allowing the user to flip/rotate the image without saving it, which does not seem to raise the ToolCommitted event.  Does that mean the changes are never added to the history, or is there some other event I can handle to clear the history after each change - or can I disable the undo history entirely?

Thanks,

Brian

0
Martin Ivanov
Telerik team
answered on 31 Oct 2018, 02:42 PM
Hello Brian,

The flipping, rotation or any other operation applied to the image will create a new instance of RadBitmap with the modified pixels. So, each change you made is actually saved into the image, but only in memory until you execute the Save command. The ToolCommiting event is not fired because the mentioned commands (flip, rotate), doesn't go through a tool when you execute them directly. In this case you can use the CommandExecuting or CommandExecuted events. 

Note that the changes applied directly via the commands are added in the history stack.

You cannot disable the history, but you can clear it on CommandExecuted. Also, you can try the CurrentImageChanged event of the History object.

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Brian
Top achievements
Rank 1
answered on 31 Oct 2018, 02:49 PM

Hi Martin,

I did come across the CurrentImageChanged event on the History object, which worked fine, however I had to hook this up in code behind so not as clean as using the CommandExecuted event, which I can hook up in XAML (it works fine too).

Thanks for all the help!

Brian

0
Martin Ivanov
Telerik team
answered on 01 Nov 2018, 09:44 AM
Hello Brian,

Indeed, using the event in code-behind is the way to go. However, here is a bit more MVVM friendly approach that you can consider for using the event. You can use an attached property which you can set on the image editor control, and in its property changed callback you can subscribe to the event and clear the history. This way you won't have code-behind in the view where the control is defined and also, you can re-use the attached behavior if needed. Here is an example implementation of the property, and also a snippet showing how to use it. I hope this helps.
public class ImageEditorUtilities
{               
    public static readonly DependencyProperty AutoClearHistoryProperty =
        DependencyProperty.RegisterAttached(
            "AutoClearHistory",
            typeof(bool),
            typeof(ImageEditorUtilities),
            new PropertyMetadata(false, OnAutoClearHistoryChanged));
 
    public static bool GetAutoClearHistory(DependencyObject obj)
    {
        return (bool)obj.GetValue(AutoClearHistoryProperty);
    }
 
    public static void SetAutoClearHistory(DependencyObject obj, bool value)
    {
        obj.SetValue(AutoClearHistoryProperty, value);
    }
 
    private static void OnAutoClearHistoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var editor = (RadImageEditor)d;
        if ((bool)e.NewValue)
        {
            editor.History.CurrentImageChanged += History_CurrentImageChanged;
        }
        else
        {
            editor.History.CurrentImageChanged -= History_CurrentImageChanged;
        }
         
    }
 
    private static void History_CurrentImageChanged(object sender, EventArgs e)
    {
        var history = (ImageHistory)sender;
        history.Clear();
    }
}

<telerik:RadImageEditor x:Name="imageEditor" local:ImageEditorUtilities.AutoClearHistory="True"/>

Regards,
Martin Ivanov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Brian
Top achievements
Rank 1
answered on 01 Nov 2018, 09:55 AM

Hi Martin,

Works perfectly!

Thanks again,

Brian

Tags
ImageEditor
Asked by
Brian
Top achievements
Rank 1
Answers by
Brian
Top achievements
Rank 1
Martin Ivanov
Telerik team
Share this question
or