Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2

Привязка DP-свойства UserControl к вложенному элементу

13.04.2019, 12:03. Показов 6249. Ответов 25

Студворк — интернет-сервис помощи студентам
Хотел реализовать одну задачу. Для реализации потребовалось создать привязку DP-свойства UserControl ко вложенному элементу.
До этого привязывал вложенный элемент к свойству UC - проблем не было. В данном случае привязка в элементе используется для другой зависимости (для связи с VM). Поэтому привязку надо создать у свойства UC.
И тут я "впал в ступор". Как раньше делал не получается. В XAML это свойство на уровне UC не видно. Делаю привязку в коде - не работает.
Чего-то не догоняю.
Ниже пример. Привязку надо сделать от свойства Result UC к свойству TextBox.Text элемента "tbResult".
В CB UC моя попытка (не рабочая) программного создания привязки.

XAML
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<UserControl x:Class="ConnectionViewWithUC.DPCalculatorUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ConnectionViewWithUC"
             mc:Ignorable="d" d:DataContext="{x:Type local:ICalculator}" >
    <StackPanel Orientation="Horizontal">
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding First, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5" MinWidth="80"/>
        <ComboBox VerticalAlignment="Center"
                  ItemsSource="{Binding Operators}"
                  SelectedItem="{Binding SelectOperator}"
                  Margin="5" MinWidth="80"/>
        <TextBox Grid.Column="2" VerticalAlignment="Center" 
                 Text="{Binding Second, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5"  MinWidth="80"/>
        <TextBlock Margin="5" VerticalAlignment="Center" Text="="/>
        <TextBox x:Name="tbResult" VerticalAlignment="Center" 
                 Text="{Binding Result, Mode=OneWay}" 
                 Margin="5" IsReadOnly="True" MinWidth="80"/>
    </StackPanel>
</UserControl>
CB
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
namespace ConnectionViewWithUC
{
    /// <summary>
    /// Логика взаимодействия для DPCalculatorUC.xaml
    /// </summary>
    public partial class DPCalculatorUC : UserControl
    {
        public DPCalculatorUC()
        {
            InitializeComponent();
            Binding bind = new Binding();
            bind.Source = tbResult;
            bind.Path = new PropertyPath("Text");
            bind.Mode = BindingMode.TwoWay;
            SetBinding(ResultProperty, bind);
        }
 
 
 
        public int? Result
        {
            get { return (int?)GetValue(ResultProperty); }
            set { SetValue(ResultProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Result.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultProperty =
            DependencyProperty.Register("Result", typeof(int?), typeof(DPCalculatorUC), new PropertyMetadata(null));
 
    }
}
На всякий случай, если понадобится интерфейс и его реализация
Кликните здесь для просмотра всего текста
Интерфейс ICalculator
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
namespace ConnectionViewWithUC
{
    public interface ICalculator
    {
        int First {  get;set; }
        int Second {  get;set; }
        OperatorsEnum SelectOperator {  get;set; }
        int? Result { get; }
        IEnumerable<OperatorsEnum> Operators { get; }
    }
    /// <summary>Перечисление допустимых  операторов</summary>
    public enum OperatorsEnum { Сложение, Умножение, Вычитание, Деление };
}
Его реализация
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
namespace ConnectionViewWithUC
{
    /// <summary>Класс вложенной VM для UC</summary>
    public class VMNestedVM : OnPropertyChangedClass, ICalculator
    {
        private int _first;
        private int _second;
        private OperatorsEnum _selectOperator;
        private int? _result;
        public static IEnumerable<OperatorsEnum> s_operators
            = Enum.GetValues(typeof(OperatorsEnum)).Cast<OperatorsEnum>();
 
 
        public int First { get => _first; set { _first = value; OnPropertyChanged(); OnResult(); } }
        public int Second { get => _second; set { _second = value; OnPropertyChanged(); OnResult(); } }
        public OperatorsEnum SelectOperator { get => _selectOperator; set { _selectOperator = value; OnPropertyChanged(); OnResult(); } }
        public int? Result { get => _result; set { _result = value; OnPropertyChanged(); } }
        public IEnumerable<OperatorsEnum> Operators => s_operators;
 
        /// <summary>Обработка полученных данных</summary>
        private void OnResult()
        {
            int? value = null;
            if (_selectOperator != OperatorsEnum.Деление || _second != 0)
                switch (_selectOperator)
                {
                    case OperatorsEnum.Сложение: value = _first + _second; break;
                    case OperatorsEnum.Умножение: value = _first * _second; break;
                    case OperatorsEnum.Вычитание: value = _first - _second; break;
                    case OperatorsEnum.Деление: value = _first / _second; break;
                }
            Result = value;
        }
 
 
    }
}


Также если понадобится основное окно и VM
Кликните здесь для просмотра всего текста
Окно
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<Window x:Class="ConnectionViewWithUC.DPMainView"
        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:ConnectionViewWithUC"
        SizeToContent="WidthAndHeight"
        mc:Ignorable="d" d:DataContext="{x:Type local:DPParentVM}" FontSize="18"
        Title="DPMainView (взаимодействие через DP свойство)">
    <Window.Resources>
        <local:DPParentVM x:Key="VM"/>
    </Window.Resources>
    <Window.DataContext>
        <Binding Mode="OneWay" Source="{StaticResource VM}"/>
    </Window.DataContext>
    <StackPanel>
        <TextBlock Margin="10">
            <Run Text="Результат вычисления:"/>
            <Run Text="{Binding Result, Mode=OneWay}"/>
        </TextBlock>
        <local:DPCalculatorUC DataContext="{Binding VMfromUC, Mode=OneWay}" Result="{Binding Result, Source={StaticResource VM}}"/>
    </StackPanel></Window>
VM
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
namespace ConnectionViewWithUC
{
    /// <summary>Класс родительской VM для View целиком</summary>
    public class DPParentVM : OnPropertyChangedClass
    {
        private int? _result;
 
        /// <summary>Вложенная VM для UC</summary>
        public VMNestedVM VMfromUC { get; } = new VMNestedVM();
 
        public int? Result { get => _result; set { _result = value; OnPropertyChanged(); } }
 
    }
}
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.04.2019, 12:03
Ответы с готовыми решениями:

Сортировка массива по вложенному элементу
Подскажите, как отсортировать многомерный ассоциативный массив по вложенному элементу? array ( 0 =&gt; array ( 'id' =&gt;...

Обращение к вложенному элементу span javascript
Добрый вечер! Помогите разобраться: Я новичок в javascript, никак не могу добиться проверки значения тэга span, вложенного в другой span....

доступ к вложенному в ListView элементу GridView
Добрый день, коллеги. Прошу помощи в решении задачи. Есть asp.net сайт. На одной из страниц сайта есть ListView, в SelectedItemY=Template...

25
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
22.09.2025, 20:48  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от JeyCi Посмотреть сообщение
т.е. практическую пользу от этого действия... т.е. если мы обновляем DataContext на новую ViewModel -- то это уже совсем др. способ работы с Model
Прошло много времени, уже деталей обсуждения не помню.
Поэтому прямой ответ, только на этот вопрос.

Например, есть UserControl подробно представляющий элемент коллекции - условно Person в коллекции People .
В Окне есть два региона. В одном представление коллекции ListBox x:Name="lbox" ItemSource="{Binding People}". В другом этот UserControl PersonUC DataContext="{Binding SelectedItem, ElementName=lbox}".
Получаем при выборе элемента в ListBox смену DataContext в UserControl.
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
22.09.2025, 21:31
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Получаем при выборе элемента в ListBox смену DataContext в UserControl.
это и есть примерно как залогиниться под определённого юзер-name (можно без пароля)...

Добавлено через 14 минут
а если в словарь ресурсов закинуть DataTemplates (для разных SelectedItem), то мы уже, наверно, не сможем менять DataContext?.. только форматирование и представление данных возможностями шире, чем стилями...

Добавлено через 3 минуты
а DP-свойства можно задать только UserControl?
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
23.09.2025, 04:30  [ТС]
Цитата Сообщение от JeyCi Посмотреть сообщение
а если в словарь ресурсов закинуть DataTemplates (для разных SelectedItem), то мы уже, наверно, не сможем менять DataContext?.
DataTemplates, в типовом случае, создают каждый раз новый экземпляр представления для нового экземпляра данных в контенте. У этого нового экземпляра представления в DataContext будет содержимое контента.

Цитата Сообщение от JeyCi Посмотреть сообщение
а DP-свойства можно задать только UserControl?
Вообще, при "максимальном правильной" реализации, дополнительная логика (в том числе DP-свойства) создаются в Custom Control.
В UserControl желательно чтобы кроме XAML больше ничего не было.

Например такой пример для первого сообщения в этой теме.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
namespace ConnectionViewWithUC
{
    // Это UserControl
    public partial class DPCalculatorUC : DPCalculatorBase 
    {
        public DPCalculatorUC()
        {
            InitializeComponent();
        }
    } 
 
    // Это Custom Control
    public class DPCalculatorBase : UserControl
    {
        protected DPCalculatorBase()
        {
            Loaded += OnLoaded;
        }
 
        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            Binding bind = new Binding();
            bind.Source = Findname("tbResult") ?? throw new Ecxeption("Обязательно должен быть элемент с именем tbResult");
            bind.Path = new PropertyPath("Text");
            bind.Mode = BindingMode.TwoWay;
            SetBinding(ResultProperty, bind);
        }
 
        public int? Result
        {
            get { return (int?)GetValue(ResultProperty); }
            set { SetValue(ResultProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Result.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultProperty =
            DependencyProperty.Register("Result", typeof(int?), typeof(DPCalculatorUC), new PropertyMetadata(null));
 
    }
}
XML
1
2
3
4
5
6
7
8
9
<local:DPCalculatorBase
             x:Class="ConnectionViewWithUC.DPCalculatorUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ConnectionViewWithUC"
             mc:Ignorable="d"
             d:DataContext="{x:Type local:ICalculator}" >
Добавлено через 7 минут
Сразу предупреждаю - пример не рабочий.
Это просто демонстрация концепции.

Конкретно в этом случае (который описывается в первом сообщении), сам подход к реализации задачи не верен.
Внешнее свойство кастомного элемента (User Control или Custom Control - не важно), нельзя использовать для внутренней привязки, которая может повлиять на логику работы элемента - это не безопасно.
Внешнюю привязку всегда можно изменить (намеренно или по незнанию) по месту использования элемента.

Я уже не помню почему мне тогда понадобилась подобное. Но сейчас, при моем нынешнем опыте, эта идея звучит как-то очень криво.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16164 / 11284 / 2891
Регистрация: 21.04.2018
Сообщений: 33,170
Записей в блоге: 2
23.09.2025, 20:44  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Цитата Сообщение от JeyCi Посмотреть сообщение
а DP-свойства можно задать только UserControl?
Например такой пример для первого сообщения в этой теме.
Забыл написать а для чего собственно это нужно.

В такой реализации, уже можно перенести привязку из кода в XAML
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
namespace ConnectionViewWithUC
{
    // Это UserControl
    public partial class DPCalculatorUC : DPCalculatorBase 
    {
        public DPCalculatorUC()
        {
            InitializeComponent();
        }
    } 
 
    // Это Custom Control
    public class DPCalculatorBase : UserControl
    {
        public int? Result
        {
            get { return (int?)GetValue(ResultProperty); }
            set { SetValue(ResultProperty, value); }
        }
 
        // Using a DependencyProperty as the backing store for Result.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultProperty =
            DependencyProperty.Register("Result", typeof(int?), typeof(DPCalculatorUC), new PropertyMetadata(null));
 
    }
}
XML
1
2
3
4
5
6
7
8
9
10
<local:DPCalculatorBase
             x:Class="ConnectionViewWithUC.DPCalculatorUC"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ConnectionViewWithUC"
             mc:Ignorable="d"
             d:DataContext="{x:Type local:ICalculator}"
             Result="{Binding Text, ElementName=tbResult}">
Этим мы убираем один из костылей, в котором мы разрешали проблему "знания" базового класса о членах производного.
Вернее не "знания", а требования задаваемого базовым классом производному.

Но проблема безопасности, когда свойство Result может быть перезадано по месту использования DPCalculatorUC, осталось.
0
264 / 153 / 33
Регистрация: 29.06.2019
Сообщений: 1,549
25.09.2025, 19:46
Цитата Сообщение от Элд Хасп Посмотреть сообщение
проблема безопасности, когда свойство Result может быть перезадано по месту использования DPCalculatorUC, осталось.
так оно (заданный Result) ведь всегда может быть перезадано? или я ошибаюсь... переназначить свойство - это же не удалить/создать объект заново...

мне почему-то кажется, что это не проблема, а как раз и задумано было, чтобы можно было переназначать свойства в зависимости от нужного (например, цвет текста при value>1000, условно говоря) - вот и вынесли это DP в отдельный класс... а за пример реализации и использования в XAML - спасибо!..

? только в каких случаях это DP подключают обычно?.. как по мне, так Styles и Templates и даже Converters - нормальные внутренние (для объекта) свойства, дальше которых уже и придумать нечего (с практической точки зрения) чтобы захотеть подключать из-вне класса ещё и DP за гранью всего, что можно задать и в объекте...
0
29.09.2025, 18:16  [ТС]
 Комментарий модератора 
Вопросы касающиеся распределения функционала вынесены в тему:
Где лучше в MVVM реализовать дополнительную логику?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
29.09.2025, 18:16

UserControl и привязка данных
Всем привет нужна помощь уже второй день мучаюсь с этой проблемой. Не понимаю какая проблема есть у UserControl что он ни в какую не хочет...

Обращение к элементу в userControl
Добрых времени суток. Есть юзер контрол, на нем лейбл, при обращении к лейблу получаю &quot;Ссылка на объект не указывает на экземпляр...

UserControl получить доступ к родительскому элементу
Как получить доступ к родительскому элементу из UserControl элемента ? Есть два контрола: public partial class UserControlMain...

Внутренняя проверка свойства в UserControl
Заморочился я сделать свой UserControl. Суть такова: контрол должен отражать числа double с тремя нулями после запятой. Имеет три открытых...

UserControl и его публичные свойства
Допустим, есть UserConrol и переменная &quot;DrawBorder&quot; Как мне сделать так, что бы DrawBorder отображалось в панели свойств среды (VS2010)? ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
26
Ответ Создать тему
Новые блоги и статьи
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
Как ИИ начал спорить и врать (возможно почуяв опасность для себя от индустрии - уход от электроники).
Hrethgir 04.08.2026
Недельный диалог, на фоне событий с НПЗ. Да, из спирта можно получать бензин, и это не сложно. Но потом в схеме я решил избавиться от насоса, при этом полностью сделав контроль подачи спирта в. . .
Термопринтер QR701
Argus19 03.08.2026
Термопринтер QR701 Купил два термопринтера QR701. На сэлф-тесте написано: Language: PC936 (GB18030). Что означает, что принтеры могут печатать только латиницу и китайские иероглифы. Так же. . .
Создание формы заимствованного документа
Maks 03.08.2026
Задача: Необходимо создать собственную форму заимствованного документа. На форме должен быть реквизит "Покупатель", а также табличная часть со следующими реквизитами: - Расчетный счет покупателя. . .
Задача предоставления скидок покупателям
Maks 03.08.2026
Задача: В документе "Продажи" необходимо реализовать функционал предоставления скидок покупателям. Скидка должна автоматически рассчитываться и подставляться в соответствующее поле при выборе. . .
Почему SEO не начинается с ключевых слов: что проверить до написания текстов
Neotwalker 01.08.2026
Когда владельцу сайта предлагают заняться SEO, первым шагом часто становится сбор запросов и написание текстов. Логика кажется понятной: 1. Находим ключевые слова. 2. Добавляем их на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru