How to get RadSplitButton from control in DropDownContent?

10 posts, 1 answers
  1. Jason
    Jason avatar
    21 posts
    Member since:
    Nov 2010

    Posted 13 Mar 2012 Link to this post

    I have a RadGridView with a column containing a RadSplitButton. Without setting StaysOpen to false, I would like to set IsOpen on the popup from one of the controls in it's DropDownContent. Obviously, I cannot use the VisualTreeHelper or other methods that walk the visual tree as it resides in a seperate window (that goes up to PopupRoot) but I should be able to use LogicalTreeHelper.GetParent() to access the popup through RadSplitButton. When I execute that method, however, I get nothing returned.

    <telerik:RadGridView>
      <telerik:RadGridView.Columns>
        <telerik:GridViewColumn>
          <telerik:GridViewColumn.CellTemplate>
            <DataTemplate>
              <telerik:RadSplitButton>
                <telerik:RadSplitButton.DropDownContent>
                  <ListBox SelectionChanged="ListBox_SelectionChanged"/>
                </telerik:RadSplitButton.DropDownContent>
              </telerik:RadSplitButton>
            </DataTemplate>
          </telerik:GridViewColumn.CellTemplate>
        </telerik:GridViewColumn>
      </telerik:RadGridView.Columns>
    </telerik:RadGridView>

    Private Sub ListBox_SelectionChanged(sender As System.Object, e As System.Windows.Controls.SelectionChangedEventArgs)
      Dim button As System.Object = LogicalTreeHelper.GetParent(e.OriginalSource)
    End Sub

    That call should return the RadSplitButton itself which I could then use to close the popup with:

    DirectCast(button, Telerik.Windows.Controls.RadSplitButton).IsOpen = False

    I can't use names because of grid but this way should work. Is this a bug that I should report or is there at least another way to do this?
  2. Jason
    Jason avatar
    21 posts
    Member since:
    Nov 2010

    Posted 14 Mar 2012 Link to this post

    I wouldn't have thought it would have to be this way; but if I walk back the visual tree to PopupRoot and then call LogicalTreeHelper.GetParent() on it, I get the Popup. I can then close it by setting it's IsOpen property to false.
  3. UI for WPF is Visual Studio 2017 Ready
  4. Answer
    Zarko
    Admin
    Zarko avatar
    755 posts

    Posted 16 Mar 2012 Link to this post

    Hello,
    If you want to find the RadSplitButton that contains the ListBox you can use our ParentOfType<T>() method like this:
    var button = listBox.ParentOfType<RadSplitButton>();
    if (button != null)
    {
        button.IsOpen = false;
    }
    I've attached a sample project that shows this so could you please examine it and if you have more questions feel free to ask?

    All the best,
    Zarko
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  5. Jason
    Jason avatar
    21 posts
    Member since:
    Nov 2010

    Posted 16 Mar 2012 Link to this post

    I've marked your post as the answer even though the extension method does the same thing as what I described simply so if other people find this they can do it in one function call without having to think about it.
  6. Bill
    Bill avatar
    9 posts
    Member since:
    Mar 2012

    Posted 30 Mar 2012 Link to this post

    Why does the RadSplitButton.DropDownContent have its own Visual Tree, with a PopupRoot?

    Is PopupRoot a telerik construct, or, is that a device provided by WPF?

    How can one look up the Visual Tree from within a RadSplitButton.DropDownContent in XAML?
  7. Zarko
    Admin
    Zarko avatar
    755 posts

    Posted 04 Apr 2012 Link to this post

    Hi Bill,
    The DropDownContent of the RadSplitButton have its own VisualTree because this is the behavior of the WPF Popup - its content is generated in a separate VisualTree (that's why if you call VisualTreeHelper.GetParent(PopupRoot) the result will be null, but the LogicalTreeHelper will still work). As for your second question - the PopupRoot is not a telerik control but a part of the Microsoft WPF Popup (in SIlverlight there's no PopupRoot).
    Unfortunately there's no straightforward way to look up the VisualTree from within the DropDownContent of the RadSplitButton. This again comes from the WPF itself because the combination of Popup and ContentPresenter stops you from going through the VisualTree:
    <Grid x:Name="root" Background="Orange">
        <Popup IsOpen="True">
            <ContentPresenter>
                <ContentPresenter.Content>
                    <Border Margin="100"
                                Background="{Binding RelativeSource={RelativeSource AncestorType=Grid},
                                                     Path=Background}"
                                Padding="30">
                        <Button Width="180"
                                    Height="30"
                                    Background="{Binding ElementName=someGrid,
                                                         Path=Background}"
                                    Content="Some button" />
                    </Border>
                </ContentPresenter.Content>
            </ContentPresenter>
        </Popup>
        <Grid x:Name="someGrid"
                 Width="50"
                 Height="50"
                 VerticalAlignment="Bottom"
                 Background="Blue" />
    </Grid>
    If you run this code you'll see that it doesn't work either (if you change the ContentPresenter to ContentControl everything works).
    I'd like to ask for your exact scenario so that we could try to find a solution for you.
    We're looking forward to hearing from you.

    Kind regards,
    Zarko
    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. Bill
    Bill avatar
    9 posts
    Member since:
    Mar 2012

    Posted 04 Apr 2012 Link to this post

    Hi Zarko,

    Thank you for the thorough explanation and example!

    My scenario is architecture related.  I want to be able to look up the VisualTree for some Commands, because I want to set the CommandParameter with the DataContext (typically, a ViewModel) of an ancestor visual element - from within XAML.

    Without this capability being available, I need to either a) hook an event to the Command and look up the Visual / Logical tree in the code-behind and call the command from the code-behind, or, b) maintain - and update - my own "ViewModelTree" on the ViewModel side when things change, so that I can find ancestor ViewModels from there.

    Thanks again for your reply.  I welcome any further thoughts that you may have.

    Bill
  9. Zarko
    Admin
    Zarko avatar
    755 posts

    Posted 06 Apr 2012 Link to this post

    Hello Bill,
    The best workaround I could think of is to create your custom style and change the ContentPresenter in the DropDown Popup to ContentControl.
    I've attached a sample project that shows this so you could examine it and if you have more questions feel free to ask.

    All the best,
    Zarko
    the Telerik team

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

  10. Bill
    Bill avatar
    9 posts
    Member since:
    Mar 2012

    Posted 06 Apr 2012 Link to this post

    Hi Zarko,

    Thank you for the excellent example.  I guess this is something I would need to do for other telerik controls as well, if I wanted to rely on this mechanism broadly in my application, correct?  And then, of course, it would be a maintenance item whenever I upgrade the telerik control code base.

    I wonder why telerik doesn't use a ContentControl instead of a ContentPresenter in the first place.   Are there any down-sides to using a ContentControl?

    Bill
  11. Zarko
    Admin
    Zarko avatar
    755 posts

    Posted 11 Apr 2012 Link to this post

    Hi Bill,
    I don't think that you'll have this problem in many of our other controls because the issue is reproducible only in the cases with this structure:
    <Popup>
        <ContentPresenter />
    </Popup>
    which in not present in all our controls (it can be found in the DropDownButton, SplitButton, DateTimePicker, ColorPicker and maybe a couple more).
    As for the ContentControl/ContentPresenter comparison - the ContentPresenter is an element that is useful inside the template of a ContentControl to specify where you want its content to be placed. It is a lot more lightweighted than the ContentControl (because the ContentControl is a control and it has a Template, Background and etc. properties that are usual for controls) and also when it Template the Presenter automatically gets its Content, ContentTemplate and ContentSelector so this code:
    <ContentPresenter />
    is equal to this:
    <ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"
        ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"  />
    And that's why in most cases we use ContentPresenters instead of ContentControls in the Templates of our controls (it's the exact same case with ItemsPresenter and ItemsControl). 
    We'll consider the problem with the Popup/ContentPresenters and we'll probably fix it for our next release.
    I've updated your telerik account and if you have further questions please feel free to ask.

    Regards,
    Zarko
    the Telerik team

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

Back to Top
UI for WPF is Visual Studio 2017 Ready