Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> WPF, DependencyObject не приводиться к UIElement, Помогите разобраться новичку с WPF 
:(
    Опции темы
lllJollyRogerlll
Дата 24.11.2016, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 20.11.2014

Репутация: нет
Всего: нет



Доброго времени суток!
Сразу предупреждаю, код ниже был написан чисто в учебных целях. Прошу не задавать вопросы, вроде: "Зачем вообще это нужно?" и т.д. Для интересующихся этим вопросом скажу откровенно - любопытно как можно реализовать подобного рода логику. Программированием увлекаюсь недавно, прошу строго не судить (хотя можно и строго, не обижусь  smile ). Сейчас начал ковырять 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>



P.S. УПС! Похоже случайно не там разместил тему. Хотел тут --> http://forum.vingrad.ru/forum/dotnet-WPF.html
Прошу простить, на форумах редкий гость. Переместить теперь не знаю как.  smile 

Это сообщение отредактировал(а) lllJollyRogerlll - 25.11.2016, 06:09
PM MAIL   Вверх
Hobotanius
Дата 30.11.2016, 01:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 24.7.2008

Репутация: нет
Всего: нет



Здравствуйте. Не уверен, что до конца понял чего Вы хотели добиться, но уверен что есть более лёгкий способ решения Вашей задачи. Например можно сделать так:

В 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)
Если это не совсем то что Вы хотели добиться, то опишите задачу в общем.

Присоединённый файл ( Кол-во скачиваний: 0 )
Присоединённый файл  WpfApplicationVUI.7z 27,13 Kb
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.1114 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.