3

I have a customized button in my interface, defined with the following style:

<Style x:Key="KinectCustomButton" TargetType="k:KinectCircleButton">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="k:KinectCircleButton">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="60*"/>
                            <RowDefinition Height="40*"/>
                        </Grid.RowDefinitions>
                        <k:KinectCircleButton Grid.Row="0" VerticalAlignment="Bottom" Foreground="{TemplateBinding Foreground}" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
                            <ContentPresenter x:Name="content"/>
                        </k:KinectCircleButton>
                        <ScrollViewer Grid.Row="1">
                            <TextBlock TextAlignment="Center" VerticalAlignment="Top" TextWrapping="Wrap"  Text="{TemplateBinding Label}" Foreground="{TemplateBinding Foreground}"  FontFamily="{TemplateBinding FontFamily}" FontSize="{TemplateBinding FontSize}" FontWeight="{TemplateBinding FontWeight}"/>
                        </ScrollViewer>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

I instantiated six of these buttons in my window. Now I need to access the ScrollViewer element for each one of these buttons. I tried this method: How can I find WPF controls by name or type? but it's not working. I also tried to access the Template property of my customized KinectCustomButton, but if I try to find the ScrollViewer instance I get the one coming from the template instead of the one in the button instance (so the text of the TextBlock inside of it is empty). Is there any method to obtain what I want?

Community
  • 1
  • 1
breathe0
  • 573
  • 1
  • 7
  • 21
  • 1
    `Now I need to access the ScrollViewer element for each one of these buttons` - What for? Don't manipulate UI elements in procedural code. – Federico Berasategui Sep 25 '13 at 15:55
  • what I am doing here is to implement the autoscroll inside my scrollviewer elements, so I need to get the references to them in order to apply my autoscroll method. if you mean that doing so will be block the UI thread (or something similar), I already took care of it – breathe0 Sep 25 '13 at 16:13

1 Answers1

1

To find the ScrollViewer in code, try the following function GetScrollViewer():

public static DependencyObject GetScrollViewer(DependencyObject Object)
{
    if (Object is ScrollViewer)
    {
        return Object;
    }

    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(Object); i++)
    {
        var child = VisualTreeHelper.GetChild(Object, i);
        var result = GetScrollViewer(child);

        if (result == null)
        {
            continue;
        }
        else
        {
            return result;
        }
    }

    return null;
}

Example of using:

if (MyListBox.Items.Count > 0) 
{
    ScrollViewer scrollViewer = GetScrollViewer(MyListBox) as ScrollViewer;

    if (scrollViewer != null)
    {
        scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + 20);
    }
}

Don't manipulate UI elements in procedural code

I think, @HighCore, wanted to say, that the use of the code for the UI element, forming grip between XAML code and C# code that could compromise when using MVVM template.

Such a relationship can cause problems when the project will increase, so, for the future, try to implement the logic for the UI element with the help of attached behaviors, commands, which could be used in the Style / Template of UI element.

Anatoliy Nikolaev
  • 22,370
  • 15
  • 69
  • 68