WPF, DependencyObject не приводиться к UIElement

 
0
 
.NET
ava
lllJollyRogerlll | 24.11.2016, 22:21
Доброго времени суток!
Сразу предупреждаю, код ниже был написан чисто в учебных целях. Прошу не задавать вопросы, вроде: "Зачем вообще это нужно?" и т.д. Для интересующихся этим вопросом скажу откровенно - любопытно как можно реализовать подобного рода логику. Программированием увлекаюсь недавно, прошу строго не судить (хотя можно и строго, не обижусь  :crazy ). Сейчас начал ковырять WPF и наткнулся на такого рода проблему - определяю атрибут Uid для объектов Label, далее хочу в коде через итерацию назначать данным Label'ам значения. То есть запустил итерацию и по целочисленному значению в коде ищу нужный мне Лейбл. Но как оказалось в WPF такой логики не предусмотрено. Подсмотрев кое что на stackowerflow наковырял вот такую расширяющую функцию:

public static UIElement FindUid(this DependencyObject parent, string uid)
        {
            var count = VisualTreeHelper.GetChildrenCount(parent);
            if (count == 0) return null;

            for (int i = 0; i < count; i++)
            {
                var el = VisualTreeHelper.GetChild(parent, i) as UIElement;
                if (el == null) continue;

                if (el.Uid == uid) return el;

                el = el.FindUid(uid);
                if (el != null) return el;
            }
            return null;
        }

На этом моя проблема не решилась. Долго бодался с тем что VisualTreeHelper.GetChildrenCount() не возвращал количество наследников. Пришлось добавить ивент txtBlockWithLabels_Loaded в мейн видоу и в него поместить вызов вышеуказанной функции.

        private void txtBlockWithLabels_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                var el = (Label)txtBlockWithLabels.FindUid("0");
                el.Content = "We did it!";

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

Но и теперь остались вопросы.
var el = VisualTreeHelper.GetChild(parent, i) as UIElement; <-- в данном фрагменте кода преобразование не происходит и переменная el остается null. При явном преобразовании компилятор ругается. Почему? Ведь насколько я понимаю класс UIElement расширяет класс DependencyObject а Лейбл в свою очередь расширяет UIElement. Должно работать.
Разметка XAML ниже.
Прошу, разъясните где я допустил ошибку.

<Window
        x:Name="MyWindow"
        x:Class="PhoneNumber_1._1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PhoneNumber_1._1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel LastChildFill="True">
        <Viewbox DockPanel.Dock="Bottom" >
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
                <Button x:Name="btnStart" Content="Start" Click="btnStart_Click"/>
                <Button x:Name="btnStop" Content="Stop"/>
                <Button x:Name="btnReset" Content="Reset"/>
            </StackPanel>
        </Viewbox>
        <Slider DockPanel.Dock="Bottom" x:Name="mySlider" Minimum="1" Maximum="100" BorderThickness="40"/>
        <Viewbox DockPanel.Dock="Top">
            <TextBlock x:Name="txtBlockWithLabels" Loaded="txtBlockWithLabels_Loaded">
                <Label x:Uid="0" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="1" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="2" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="3" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="4" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="5" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="6" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="7" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="8" BorderThickness="2" BorderBrush="Blue"/>
                <Label x:Uid="9" BorderThickness="2" BorderBrush="Blue"/>
            </TextBlock>
        </Viewbox>
    </DockPanel>
</Window>

Kommentare (1)
ava
Hobotanius | 30.11.2016, 01:40 #
Здравствуйте. Не уверен, что до конца понял чего Вы хотели добиться, но уверен что есть более лёгкий способ решения Вашей задачи. Например можно сделать так:

В App.xaml

...
    <Application.Resources>
        ...
        <Style TargetType="Label">
            <Setter Property="BorderThickness" Value="2" />
            <Setter Property="BorderBrush" Value="Blue" />
        </Style>
        ...
    </Application.Resources>
...


В декларации Вашего окна:

...
            <TextBlock Name="txtBlockWithLabels" Loaded="txtBlockWithLabels_Loaded">
                <Label Name="l0" />
                <Label Name="l1" />
                <Label Name="l2" />
                <Label Name="l3" />
                <Label Name="l4" />
                <Label Name="l5" />
                <Label Name="l6" />
                <Label Name="l7" />
                <Label Name="l8" />
                <Label Name="l9" />
            </TextBlock>
...


В коде Вашего окна

        private void txtBlockWithLabels_Loaded(object sender, RoutedEventArgs e)
        {
            for (int i = 0 ; i < 10; i++ )
            {
                Label el = txtBlockWithLabels.FindName("l"+ i.ToString()) as Label;
                el.Content = "L" + i.ToString();
            }

        }


Теперь всё работает без всяких: public static UIElement FindUid(this DependencyObject parent, string uid)
Если это не совсем то что Вы хотели добиться, то опишите задачу в общем.
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden