How to remove SeriesItemLabel from tab stops

8 posts, 0 answers
  1. Antti
    Antti avatar
    23 posts
    Member since:
    May 2011

    Posted 03 Jan 2012 Link to this post

    Hi,

    I would like to remove charts from the tab stops altogether, so that when moving with the tabulator key, the focus would never stop in any part of the charts. I have succeeded with all other elements, but SeriesItemLabels always seem to be tab stops. I have SeriesItemLableStyle defined like this:

    seriesMapping.SeriesDefinition.SeriesItemLabelStyle = (Style)Application.Current.Resources["SeriesItemLabelStyle"];
    

    And here is the style:

    <Style x:Key="SeriesItemLabelStyle" TargetType="telerik:SeriesItemLabel">
            <Setter Property="IsTabStop" Value="False" />
            ...

    This won't do the trick however. Any suggestions on what could I try?

    Regards,
    Antti Nyman
  2. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 05 Jan 2012 Link to this post

    Hi Antti,

    You are right. It seems that IsTabStop doesn't work when set on SeriesItemLabels. I have forwarded your report to our developers for further investigation.

    You can try another approach for skipping focus on the radchart. When the chart gets focus you can find the next element that should be focused from the visual tree and give the focus to it. Here is some code:

        this.radChart.GotFocus += radChart_GotFocus;
    }
     
    void radChart_GotFocus(object sender, RoutedEventArgs e)
    {
        int chartIndex = LayoutRoot.Children.IndexOf(this.radChart);
        Control nextChild = LayoutRoot.Children.Skip(chartIndex + 1).FirstOrDefault(c => c is Control) as Control;
        if (nextChild != null)
        {
            nextChild.Focus();
        }
    }

    In our case the RadChart was contained in the main grid called LayoutRoot. This approach doesn't require setting IsTabStop, so you won't hit the problem with SeriesItemLabel.

    Hope this helps!

    Regards,
    Yavor
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  3. DevCraft banner
  4. Richard
    Richard avatar
    30 posts
    Member since:
    Oct 2010

    Posted 15 Feb 2012 Link to this post

    Hi Yavor,


    I'm also having this problem, with a pie chart. I'd like the user to be able to skip the chart entirely in the tab order, since (as far as I know) the user cannot interact with the RadChart using the keyboard.

    Your approach for skipping focus works when tabbing in the forward direction. But when pressing Shift+Tab to go backwards, the user ends up getting stuck, since the chart always bounces them forwards again. The user has to tab all the way around in the forward direction. So I'm wondering if there is a better solution.

    In addition to SeriesItemLabel, there are tab stops for the following control types inside the RadChart (I found them using Silverlight Spy):
    Series, Pie, RadTransitionControl, AdditionalPlotAreaAxes2DContainer, DragZoomLayerControl

    I was able to get rid of the tab stops for Series and Pie by defining implicit styles for these types. But this does not work for the other ones. Is there anything else I could try?


    Thanks for your help,
    Richard
  5. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 17 Feb 2012 Link to this post

    Hi Richard,

    You can try moving the RadChart up in xaml, so that it receives focus first. Then in the GotFocus event handler add this:
    private void radChart_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as Control).IsTabStop = false;
     
        int chartIndex = LayoutRoot.Children.IndexOf(this.radChart);
        Control nextChild = LayoutRoot.Children.Skip(chartIndex + 1).FirstOrDefault(c => c is Control) as Control;
        if (nextChild != null)
        {
            nextChild.Focus();
        }
    }

    This code will make sure that once you've got keyboard focus you won't get it again. The logic for passing the focus will work correctly as you will (most often) acquire tab focus in the forward direction going from RadChart.

    Another approach could be to get all visual children of the RadChart that are Controls and again set the IsTabStop to false.

    Greetings,
    Yavor
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  6. Richard
    Richard avatar
    30 posts
    Member since:
    Oct 2010

    Posted 17 Feb 2012 Link to this post

    Hi Yavor,


    Thanks for your answer.

    I tried your sample code though, and it's not working for me - Shift+Tabbing backwards after tabbing through the chart still gets me stuck on the control after the chart.

    Setting IsTabStop=False on the chart prevents the chart itself from becoming the focused element, but it doesn't prevent children of the chart (such as the SeriesItemLabel) from getting the focus. The focus event then bubbles up the visual tree from the SeriesItemLabel to the chart. The radChart_GotFocus handler is called again, and again it moves the focus to the next sibling element of the chart.

    Earlier, I also tried traversing the visual tree and setting IsTabStop=False on all children. But it didn't work for me - I'm not sure why. I confirmed in the debugger that IsTabStop was set to False on each control; but when I tabbed through the UI, the tab stops were still there. Maybe I was making my changes at the wrong point in the control lifecycle, and something set them back to True afterwards.

    Anyway, this is probably not that critical for us right now. I'll let you know if it does turn out to be a serious problem.


    Thanks for your help,
    Richard
  7. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 20 Feb 2012 Link to this post

    Hi Richard,

    I suppose that the traversing of the visual tree didn't work because by the time you are doing it the chart hasn't generated its children yet. You can hook up to the DataBound event as by then the chart will be prepared as a visual structure. Here is some code:

    public MainPage()
    {
        InitializeComponent();
     
        radChart.DataBound += radChart_DataBound;
        radChart.ItemsSource = new int[] { 1, 2, 3 };
    }
     
    private void radChart_DataBound(object sender, ChartDataBoundEventArgs e)
    {
        foreach (var control in this.radChart.ChildrenOfType<Control>())
        {
            control.IsTabStop = false;
        }
    }

    Hope this helps! Greetings,
    Yavor
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  8. Tony
    Tony  avatar
    9 posts
    Member since:
    Feb 2011

    Posted 20 Feb 2012 Link to this post

    Hi Yavor,


    Thanks again - I've finally got it working.

    It looks like the DataBound event is too early as well - in the DataBound event handler, ChildrenOfType<Control>() returned zero elements.

    I was able to get it working though by putting the code in the SizeChanged handler. Here is what I ended up with:

    <c:RadChart x:Name="Chart" IsTabStop="False" SizeChanged="Chart_SizeChanged">
      <!-- ... -->
    </c:RadChart>

    private void Chart_SizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
    {
        Debug.WriteLine("Size changed");
     
        var controls = Chart.ChildrenOfType<Control>().Where(x => x.IsTabStop).ToList();
     
        foreach (var control in controls)
        {
            control.IsTabStop = false;
            Debug.WriteLine("{0} {1} IsTabStop -> {2}", control, control.Name, control.IsTabStop);
        }
    }


    Thanks,
    Richard
  9. Yavor
    Admin
    Yavor avatar
    401 posts

    Posted 23 Feb 2012 Link to this post

    Hi Tony,

    Make sure that you remove the handler once you set the tab stops. Traversing the visual tree on every size changed can have serious performance implications.

    Kind regards,
    Yavor
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top
DevCraft banner