Лучший отвечающий
WPF. DependencyProperty. UserControl

Вопрос
-
Хочу разобраться с работой DependencyProperty. Создал простой начальный пример (по образу и подобию, грешен). Но не работает.
XAML:
<UserControl x:Class="DP_Text.UserControl1" 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:uc="DP_Text" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid> <TextBox Text="{Binding Eklmn}"/> </Grid> </UserControl>
C#
using System; using System.Windows; using System.Windows.Controls; namespace DP_Text { public partial class UserControl1 : UserControl { public static DependencyProperty EklmnProperty = DependencyProperty.Register("Eklmn", typeof(string), typeof(UserControl1), new UIPropertyMetadata(String.Empty)); public string Eklmn { get { return (string)GetValue(EklmnProperty); } set { SetValue(EklmnProperty, value); } } public UserControl1() { InitializeComponent(); } } }
UserControl вставляю в Window
<Window x:Class="DP_Text.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" DataContext="{Binding RelativeSource={RelativeSource Self}}" xmlns:uc="clr-namespace:DP_Text"> <StackPanel Name="MyStackPanel"> <uc:UserControl1 Eklmn="Text goes here" /> </StackPanel> </Window>
По идее, в TextBox должен отобразиться текст из Property Eklmn. Но что-то идёт не так.25 марта 2013 г. 10:22
Ответы
-
Насколько я понял из всего,создание нового свойства, не характерного для элемента возможно только через обёртку ввиде usercontrol`а?
Нет, есть еще наследование. Например, добавляю в WPF проект новый класс:
public class SelectableLabel : Label { public SelectableLabel() : base() { this.Background = new SolidColorBrush(Colors.Red); } public bool IsSelected { get { return (bool)GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } // Using a DependencyProperty as the backing store for IsSelected. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(SelectableLabel), new UIPropertyMetadata(false, IsSelectedChanged)); private static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { SelectableLabel label = sender as SelectableLabel; if (label != null) { if (label.IsSelected) { label.Background = new SolidColorBrush(Colors.Green); } else { label.Background = new SolidColorBrush(Colors.Red); } } } }
Меняем разметку главной формы:
<Window xmlns:my="clr-namespace:WpfApplication34" x:Class="WpfApplication34.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <StackPanel> <my:SelectableLabel Content="Привет" IsSelected="True" /> <my:SelectableLabel Content="Пока" IsSelected="False" /> </StackPanel> </Window>
Запускаем:
Как видите, я обошелся и без UserControl
- Помечено в качестве ответа rz3rr 26 марта 2013 г. 6:35
25 марта 2013 г. 17:57Отвечающий
Все ответы
-
Попробуйте поменять определение свойства на:
public static DependencyProperty EklmnProperty = DependencyProperty.Register("Eklmn", typeof(string), typeof(UserControl1), new UIPropertyMetadata(String.Empty, textChanged));
private static void textChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var c = sender as UserControl1;
if (c != null)
{
c.textBlock1.text = e.NewValue;
}
}а в XAML разметке добавить имя для текстового блока установить имя textBlock1
25 марта 2013 г. 11:00 -
добавил
DataContext="{Binding RelativeSource={RelativeSource Self}}"
в "шапке" UserControl - всё заработало
Ради интереса сейчас опробую Ваш вариант (без DataContext).
25 марта 2013 г. 11:03 -
Brash_Oб работает и Ваш вариант с маленькой корректировкой
. . . . . . c.textBlock1.Text = (string)e.NewValue; . . . . . .
Спасибо.- Изменено rz3rr 25 марта 2013 г. 11:09
25 марта 2013 г. 11:08 -
А как программно обратиться к Property Eklmn? И из usercontrol и из window?
Ну, например UserControl.Eklmn ?
- Изменено rz3rr 25 марта 2013 г. 11:49
25 марта 2013 г. 11:47 -
А как программно обратиться к Property Eklmn? И из usercontrol и из window?
Тему рано закрыл ))
Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!
25 марта 2013 г. 11:50Отвечающий -
Чуть не так выразился. Объясню. Добавил ещё
public static DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(Label), new UIPropertyMetadata(String.Empty, IsSelectedChanged)); public bool IsSelected { get { return (bool) GetValue(IsSelectedProperty); } set{SetValue(IsSelectedProperty,value);} } private static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var c = sender as Label; if (c != null) { MessageBox.Show("Сoстояние изменено на " + e.NewValue); } }
в XAML usercontrol`a добавил
<Label Name="Label1"/> <Button Click="button_click"/>
а тут хочу
private void button_click(object sender, RoutedEventArgs e) { Label1.IsSelected = true; }
но ругается на IsSelected, что нет такого определения.
- Изменено rz3rr 25 марта 2013 г. 12:06
25 марта 2013 г. 12:02 -
IsSelected не является частью Label. Он является свойством вашего UserControl. Label же это запчасти внутри UserControl, так сказать представление внештатного вида.
достаточно просто IsSelected = true;
но не уверен, что вы хотите именно это. Вообще для более лучшего понимания DependencyProperty и UserControl в целом советую почитать книгу Мэтью МакДонольда "WPF для профессионалов с примерами на C#"
Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!
25 марта 2013 г. 12:23Отвечающий -
Есть такая книга в pdf. Сейчас взгляну. Спасибо. Тему пока не закрываю.
25 марта 2013 г. 12:26 -
Насколько я понял из всего,создание нового свойства, не характерного для элемента возможно только через обёртку ввиде usercontrol`а?
25 марта 2013 г. 16:01 -
Насколько я понял из всего,создание нового свойства, не характерного для элемента возможно только через обёртку ввиде usercontrol`а?
Женат на WPF. Тайно встречаюсь с WinRT. Не сложилось с C#!
25 марта 2013 г. 16:07Отвечающий -
Насколько я понял из всего,создание нового свойства, не характерного для элемента возможно только через обёртку ввиде usercontrol`а?
Нет, есть еще наследование. Например, добавляю в WPF проект новый класс:
public class SelectableLabel : Label { public SelectableLabel() : base() { this.Background = new SolidColorBrush(Colors.Red); } public bool IsSelected { get { return (bool)GetValue(IsSelectedProperty); } set { SetValue(IsSelectedProperty, value); } } // Using a DependencyProperty as the backing store for IsSelected. This enables animation, styling, binding, etc... public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(SelectableLabel), new UIPropertyMetadata(false, IsSelectedChanged)); private static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { SelectableLabel label = sender as SelectableLabel; if (label != null) { if (label.IsSelected) { label.Background = new SolidColorBrush(Colors.Green); } else { label.Background = new SolidColorBrush(Colors.Red); } } } }
Меняем разметку главной формы:
<Window xmlns:my="clr-namespace:WpfApplication34" x:Class="WpfApplication34.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <StackPanel> <my:SelectableLabel Content="Привет" IsSelected="True" /> <my:SelectableLabel Content="Пока" IsSelected="False" /> </StackPanel> </Window>
Запускаем:
Как видите, я обошелся и без UserControl
- Помечено в качестве ответа rz3rr 26 марта 2013 г. 6:35
25 марта 2013 г. 17:57Отвечающий -
Спасибо... Сегодня нет возможности опробовать, но почти то, что нужно.
25 марта 2013 г. 18:49 -
тут ещё надо, видимо, добавить ссылку на класс
xmlns:my="clr-namespace:WpfApplication34"
26 марта 2013 г. 6:29 -
Очень похоже на реализацию UserControl`ом, но без XAML.
Всё работает. Всем спасибо.
26 марта 2013 г. 6:35 -
тут ещё надо, видимо, добавить ссылку на класс
xmlns:my="clr-namespace:WpfApplication34"
Она там есть, просто в первой строке...26 марта 2013 г. 7:55Отвечающий -
сорь... не заметил )
26 марта 2013 г. 8:11