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

Tell me how the table cell alignment magic happens

4 Answers 59 Views
RichTextBox
This is a migrated thread and some comments may be shown as answers.
Will
Top achievements
Rank 1
Will asked on 22 Aug 2012, 05:11 PM
I've got a RRTB with the RRTBRUI in my application, where table cell alignment is all botched.

(The ribbon was created by dropping the RRTBRUI on the design surface.  I then removed editing options I don't want the user to have.)

To illustrate, please view the attached image.  You can see that not only is 1) the context menu alignment button 2) not being respected within the design surface, but also 3) within the ribbon you can click an entire row of alignment buttons.

To try and debug this, I have
  • copied the exact markup into a minimal solution
  • compared mouse events
  • examined application resources
  • cranked wpf trace levels to ALL
  • Listened to RTB command events

Copied the markup exactly, and was unable to repro in a minimal solution.  Damn.

I watched mouse events in both a working example and in my non-working example, and did not see events being handled any differently.  Damn.

I checked to see if there were any Styles with default keys that were interfering with the RadToggleButton in any way, and had none.  Damn.

Cranked up all trace levels and repro'd.  Nothing.  Well, actually LOTS of nothing.  But 99% was binding failures before the commands binding was updated ("DataItem=null"), and the rest were about "Path=Menu.IconColumnWidth".  Damn.

Listened to CommandError, CommandExecuting, and CommandExecuted.  Verified the correct command and the correct command parameters are being passed every time, for every button.  And CommandError never fires when using these buttons.  Damn.

So that leaves me stumped.  I know the RRTBRUI is doing stuff in the background, probably walking its children, managing their state.  But I don't know how this is happening, so I can't figure out what is going wrong.

How does the RRTBRUI handle cell alignment?  What are the things that could go wrong?  Any ideas?

4 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 27 Aug 2012, 11:57 AM
Hello Will,

Thank you for your feedback. However, we haven't encountered such an issue before and unfortunately without any steps to reproduce the problem, we cannot comment on it.

Can you please send us a cut of your solution where the problem persists so that we can help you? If you open a support ticket and attach your solution, it will not be used for any other purpose than investigating the case.

Thank you for your understanding.

All the best,
Martin
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Will
Top achievements
Rank 1
answered on 27 Aug 2012, 12:06 PM
Unfortunately, I'd have to spend a decent amount of time cutting it out.  As in, it is less costly to throw cell positioning away rather than attempt to isolate the issue.

Can I just get the algorithm for how the ribbon UI manages these buttons?  What methods it calls, what is it listening for, how is this done?  
If you're using DependencyPropertyDescriptor to add a watch to a DP, and if you don't keep a reference to the DPD you are using to add the watch

//this is pseudocode; doing it from memory
var foo = DependencyPropertyDescriptor.FromProperty(lah, dedah);
foo.AddValueChanged(someObject, someMethod);
// foo goes out of scope here

then I think I know what's happening, and it isn't anything you guys are doing.  Well, other than the fact that DPDs can become detached, discarded and collected without you ever knowing.  This can happen in some rare cases, such as within a wf4 designer (my situation).

So, if this is part of the ribbon "magic", then I know what the problem is, what feature request to submit to you guys, and what my solution is (none, for now).  If you're doing something else, then I can investigate other avenues.
0
Accepted
Martin Ivanov
Telerik team
answered on 29 Aug 2012, 04:24 PM
Hi Will,

Assuming you have auto generated RadRichTextBoxRibbonUI or you have copied the code from the demos, the buttons will be wired using the RichTextCommand attached property specified:

public static readonly DependencyProperty RichTextCommandProperty =
           DependencyProperty.RegisterAttached(
           "RichTextCommand",
           typeof(RichTextBoxCommandBase),
           typeof(RadRichTextBoxRibbonUI),
           new System.Windows.PropertyMetadata(new PropertyChangedCallback(OnRichTextBoxCommandChanged)));

and it's callback:

private static void OnRichTextBoxCommandChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
           ...
 
            else if (o is RadRibbonToggleButton && (e.NewValue is ChangeTextAlignmentCommand || e.OldValue is ChangeTextAlignmentCommand))
            {
                AttachChangeTextAlignmentCommand(
                    o as RadRibbonToggleButton,
                    e.OldValue as ChangeTextAlignmentCommand,
                    e.NewValue as ChangeTextAlignmentCommand);
            }
         ...
         if (e.OldValue != null && e.NewValue == null)
            {
                ClearAttachedProperties(o);
            }
        }

and here is how the command is attached to the button:

private static void AttachChangeTextAlignmentCommand(
        RadRibbonToggleButton radRibbonToggleButton,
        ChangeTextAlignmentCommand oldCommand,
        ChangeTextAlignmentCommand newCommand)
    {
        radRibbonToggleButton.Command = newCommand;
 
        if (oldCommand != null)
        {
            EventHandler<StylePropertyChangedEventArgs<RadTextAlignment?>> oldHandler =
                GetToggleHandlerButton<RadTextAlignment?>(radRibbonToggleButton);
 
            if (oldHandler != null)
            {
                oldCommand.TextAlignmentChanged -= oldHandler;
            }
        }
 
        if (newCommand != null)
        {
            EventHandler<StylePropertyChangedEventArgs<RadTextAlignment?>> newHandler =
                new EventHandler<StylePropertyChangedEventArgs<RadTextAlignment?>>((s, e) =>
                {
                    bool isChecked = false;
 
                    RadTextAlignment commandAlignment;
                    if (ChangeTextAlignmentCommand.TryConvertCommandParameter(radRibbonToggleButton.CommandParameter, out commandAlignment))
                    {
                        isChecked = e.NewValue == commandAlignment;
                    }
                    else
                    {
                        isChecked = false;
                    }
 
                    radRibbonToggleButton.IsChecked = isChecked;
                });
 
            newHandler.Invoke(newCommand, newCommand.GetEventArgs());
 
            RadRichTextBoxRibbonUI.SetCommandStateChangedHandler(radRibbonToggleButton, newHandler);
            newCommand.TextAlignmentChanged += newHandler;
        }
    }

where 

private static void SetCommandStateChangedHandler(DependencyObject obj, object value)
      {
          obj.SetValue(CommandStateChangedHandlerProperty, value);
      }
 
      private static readonly DependencyProperty CommandStateChangedHandlerProperty =
          DependencyProperty.RegisterAttached("CommandStateChangedHandler", typeof(object), typeof(RadRichTextBoxRibbonUI), null);

You can download the source of all controls from your account and further investigate what the command does.

We hope this helps. Don't hesitate to contact us if you have other questions or comments.


Greetings,
Martin
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Will
Top achievements
Rank 1
answered on 29 Aug 2012, 04:31 PM
Thanks for that info.  Now I'll have something to go off of when we move the resolution for this out of the backlog.
Tags
RichTextBox
Asked by
Will
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Will
Top achievements
Rank 1
Share this question
or