Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > DependencyProperty и DependencyObject


Автор: Larrr 9.1.2009, 14:37
Привет, уважаемые. Вопрос такой:

Мне надо сделать UserControl со свойством PropertyName, который потом можно было бы использовать в другом окне. Причем прямо набиндить PropertyName:

Код

<typescontrol:DataTypeControl Name="DataTypesENFControl" PropertyName="{Binding Name}">
</typescontrol:DataTypeControl>


(который потом не меняется - мне достаточно его один раз записать и запомнить).

Я уже нашла, что PropertyName должен быть DependencyProperty. Как было написано в моей умной книжке, я сделала так:

Код

 public partial class DataTypeControl : UserControl
    {
        public static readonly DependencyProperty PropertyNameProperty = 
            DependencyProperty.Register("PropertyName", typeof(String), typeof(DataTypeControl));
        
        
        public String PropertyName
        {
            set
            {
                SetValue(PropertyNameProperty, value);
            }
            get
            {
                return GetValue(PropertyNameProperty).ToString();
            }
        }
    ...
    }



Проблема в том, что оно не работает. При попытке набиндить что-то в PropertyName пишется ошибка 

"A 'Binding' cannot be set on the 'PropertyName' property of type 'DataTypeControl'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."

Где ошибка, как сделать так, чтобы оно работало?

Автор: Adm0r 11.1.2009, 19:50
попробуйте так
Код

 public partial class DataTypeControl : UserControl
    {
        private String propertyName
        public static readonly DependencyProperty PropertyNameProperty = 
            DependencyProperty.Register("PropertyName", typeof(String), typeof(DataTypeControl), new PropertyMetadata(new PropertyChangedCallback(DataTypeControl.OnPropertyNameChanged)));
        private static void OnPropertyNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
       {
           ((DataTypeControl)d).propertyName = e.NewValue.ToString();
       }
        
        public String PropertyName
        {
            set
            {
                SetValue(PropertyNameProperty, value);
            }
            get
            {
                return GetValue(PropertyNameProperty).ToString();
            }
        }
    ...
    }

Автор: Partizan 11.1.2009, 21:10
Adm0r, разница какая между вашим кодом и кодом Larrr?))))


Larrr, в вашем коде всё правильно вроде...проблема ещё не решилась?

Автор: Adm0r 12.1.2009, 11:41
Partizan,  разница в том что мой код работает, а код 
Larrr, - нет

Я практик, а не теоретик, поэтому популярно обьяснить не смогу, - но  код Larrr, не предоставляет механизм изменения DependencyProperty как свойсва DependencyObject. 

Автор: Partizan 13.1.2009, 16:06
Цитата

Я практик, а не теоретик, поэтому популярно обьяснить не смогу, - но  код Larrr, не предоставляет механизм изменения DependencyProperty как свойсва DependencyObject. 


Тогда советую пойти и подучить матчасть....ваш код избыточен....в нём много лишнего...


Larrr, я накидал примерчик...у меня всё работает...

Код

    /// <summary>
    /// Interaction logic for DataTypeControl.xaml
    /// </summary>
    public partial class DataTypeControl : UserControl
    {


        public string PropertyName
        {
            get { return (string)GetValue(PropertyNameProperty); }
            set { SetValue(PropertyNameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PropertyName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PropertyNameProperty =
            DependencyProperty.Register("PropertyName", typeof(string), typeof(DataTypeControl), new UIPropertyMetadata(""));



        public DataTypeControl()
        {
            InitializeComponent();
        }
    }


Код

<Window x:Class="My_WPF_Tests.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:My_WPF_Tests"
    Title="Window1" Height="300" Width="300" Name="mainWnd">
    <Grid>
        <DockPanel x:Name="dockPanel">
            <src:DataTypeControl PropertyName="{Binding ElementName=mainWnd, Path=Name}" DockPanel.Dock="Top" Height="100" HorizontalAlignment="Stretch" Width="280" />
            <Button Click="Button_Click" DockPanel.Dock="Bottom" Height="20">OK</Button>
        </DockPanel>
    </Grid>



Автор: Adm0r 14.1.2009, 11:46
злые вы. за пример спасибо, код действительно лучше.

ПС. Если вы накидали примерчик, то могли бы не копипастить в СВОЙ код чужые коментарии.
http://blogs.interknowlogy.com/joelrumerman/archive/2007/04/03/12497.aspx(почти - идентификатор свойсва изменился)

Автор: Partizan 14.1.2009, 12:24
Adm0r, мы не злые - это раз...

по поводу второго - опять же могу только посоветовать подучить матчасть....


p.s. обвиняете меня в плагиате????  smile 
это меня действительно чуть-чуть раздражает...

совет: прежде чем разбрасываться голословнми обвинениями,
почитайте про code snippets и попробуйте попользовать code snippet для генерации dependency property...сразу все подозрения отпадут...

Автор: Adm0r 14.1.2009, 13:39
простите если обидел. У меня в студии code snippets просто генерирует абсолютно непохожий код, вот я и подумал... извините.

по поводу учить матчасть, вы уж извините, но адекватно посылать учить матчасть принято с ссылкой на ту самую матчасть. В противном случае у собеседника создается впечатление что вы его посылаете на 3 веселых буквы.

Автор: Partizan 14.1.2009, 13:43
Adm0r, асболютно непохожий - это какой  smile 

Матчасть: http://msdn.microsoft.com/en-us/library/ms752914.aspx

Автор: Adm0r 14.1.2009, 14:10
Код

public static global::System.Workflow.ComponentModel.DependencyProperty MyPropertyProperty = global::System.Workflow.ComponentModel.DependencyProperty.Register("MyProperty", typeof(string), typeof(UnigueList));

        [System.ComponentModel.DescriptionAttribute("MyProperty")]
        [System.ComponentModel.CategoryAttribute("MyProperty Category")]
        [System.ComponentModel.BrowsableAttribute(true)]
        [System.ComponentModel.DesignerSerializationVisibilityAttribute(System.ComponentModel.DesignerSerializationVisibility.Visible)]
        public string MyProperty
        {
            get
            {
                return ((string)(base.GetValue(UnigueList.MyPropertyProperty)));
            }
            set
            {
                base.SetValue(UnigueList.MyPropertyProperty, value);
            }
        }

мсдн у меня и на машине есть....ладно, можете мне не отвечать, все равно тут на форуме учиться не у кого...я ушел. Всем пока

Автор: Partizan 14.1.2009, 14:26
Adm0r, мде....подумал с ходу, что код С++...у вас DependencyProperty не оттуда берётся)

Добавлено через 3 минуты и 13 секунд
такое ощущение, что Вы создали проект WWF....

Автор: namespace 19.2.2009, 21:08
есть мой контрол, при его использовании в конкретном окне мне необходимо установить ширину колонки грида (корневой элемент в
контроле и окне Grid), хотел что бы эта ширина биндилась в хамле при определнии контрола написал так:
Код

<Products:ProductControl Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="3" 
      LabelWidth="{Binding ElementName=grid, Path=ColumnDefinitions[0].Width}" x:Name="productControl" />

в самом контроле сделал Dependency свойство:
Код

        public GridLength LabelWidth
        {
            get
            {
                return (GridLength)this.GetValue(LabelWidthProperty);
            }
            set
            {
                this.SetValue(LabelWidthProperty, value);
            }
        }

        public static readonly DependencyProperty LabelWidthProperty =
            DependencyProperty.Register("LabelWidth", typeof(GridLength), typeof(ColumnDefinition), new UIPropertyMetadata(new
            GridLength(100),new PropertyChangedCallback(OnLabelWidthChanged)));

        private static void OnLabelWidthChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ((ColumnDefinition)d).Width = (GridLength)e.NewValue;
        }

получаю исключение:
Error    1    A 'Binding' cannot be set on the 'LabelWidth' property of type 'ProductControl'. 
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
в чем я не прав?


Автор: Partizan 19.2.2009, 21:44
namespace, ProductControl от кого наследуется?

Автор: namespace 19.2.2009, 21:46
UserControl

Автор: Partizan 19.2.2009, 21:56
namespace, а почему Owner-ом выставлен класс ColumnDefinition??????

Цитата

 typeof(ColumnDefinition)


Выставьте вместо ColumnDefinition класс ProductControl

Автор: namespace 19.2.2009, 22:00
а балбес, спасибо все правильно

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)