[WPF] binding подсвойств
От: Neco  
Дата: 03.08.11 07:36
Оценка:
Вот такой xaml
        <TextBox Name="txtToSearch" Grid.Row="3" Text="example" />
        <my:EntityList Name="grid1" Grid.Row="0" Tag="{Binding ElementName=txtToSearch, Path=Text}">
            <my:EntityList.ListSource>
                <my:ListSourceConfig Test="{Binding ElementName=txtToSearch, Path=Text}" TypeName="TestWpfApplication.AppServRef.EntityServiceClient, TestWpfApplication" SelectMethod="GetByName">
                    <my:ListSourceConfig.Parameters>
                        <my:ListSourceParameter Name="partOfName" Value="{Binding ElementName=txtToSearch, Path=Text, Mode=OneWay}" />
                        <my:ListSourceParameter Name="options" />
                    </my:ListSourceConfig.Parameters>
                </my:ListSourceConfig>
            </my:EntityList.ListSource>
        </my:EntityList>

проблема в том, что привязка к свойству EntityList.Tag работает, а привязки к свойствам ListSourceConfig.Test и ListSourceParameter.Value нет.
в Output такие ошибки:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Text; DataItem=null; target element is 'ListSourceConfig' (HashCode=14259084); target property is 'Test' (type 'String')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Text; DataItem=null; target element is 'ListSourceParameter' (HashCode=16880676); target property is 'Value' (type 'String')

гугление даёт что-то наподобие здесь:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/aff23943-5483-40b2-816b-4ce687bc6bf8/
но при наследовании от FrameworkElement (до этого было от DependencyObject) получаю другую ошибку:
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'ElementName=txtToSearch'. BindingExpression:Path=Text; DataItem=null; target element is 'ListSourceConfig' (Name=''); target property is 'Test' (type 'String')


может кто-нибудь объяснить, а в чём суть проблемы? Т.е. это ведь просто подсвойства — в чём концептуальная разница между EntityList.Tag и EntityList.ListSourceConfig.Test? Я понимаю, когда в шаблоне нельзя обратиться к наружным элементам, но вот так...
ну и собственно как грамотно решать это?

p.s. пытаюсь осилить вот эти буквы http://blogs.msdn.com/b/nickkramer/archive/2006/08/18/705116.aspx, но вывод мне там не очень нравится — это что же каждый раз через ресурс всё делать?..
всю ночь не ем, весь день не сплю — устаю
Re: [WPF] binding подсвойств
От: MxMsk Португалия  
Дата: 03.08.11 08:01
Оценка: 6 (1)
Здравствуйте, Neco, Вы писали:

N>может кто-нибудь объяснить, а в чём суть проблемы? Т.е. это ведь просто подсвойства — в чём концептуальная разница между EntityList.Tag и EntityList.ListSourceConfig.Test? Я понимаю, когда в шаблоне нельзя обратиться к наружным элементам, но вот так...

N>ну и собственно как грамотно решать это?
Binding ищет элемент в визуальном дереве, а ListSourceParameter в визуальное дерево не входит. Что можно сделать? На вскидку, должен сработать такой вариант. Наследуем ListSourceParameter от FrameworkElement и присваиваем ему
DataContext="{x:Reference txtToSearch}"

Тогда должен сработать Binding без указания источника:
Value="{Binding Path=Text, Mode=OneWay}"


Решение выглядит костыльно в силу назначения FrameworkElement. Правильный же вариант будет выглядеть громоздко. Потребуется унаследовать ListSourceConfig от Freezable, а коллекцию ListSourceConfig.Parameters от FreezableCollection. ListSourceParameter тоже придется сделать Freezable, но зато в конечном счете это позволит всем элементам ListSourceConfig.Parameters использовать Binding полноценно. Почитай об inheritance context.
Re[2]: [WPF] binding подсвойств
От: Neco  
Дата: 03.08.11 08:17
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Решение выглядит костыльно в силу назначения FrameworkElement. Правильный же вариант будет выглядеть громоздко. Потребуется унаследовать ListSourceConfig от Freezable, а коллекцию ListSourceConfig.Parameters от FreezableCollection. ListSourceParameter тоже придется сделать Freezable, но зато в конечном счете это позволит всем элементам ListSourceConfig.Parameters использовать Binding полноценно. Почитай об inheritance context.

спасибо!
собственно громоздкость второго (правильного варианта) для меня выражается в том, что реализация Freezable склоняет к тому, чтобы иметь все свойства как DependencyProperty — чего я собственно собирался избежать, поскольку привязка мне нужна будет к одному-двум свойствам.
Однако, раз взялся за гуж... вероятно надо привыкнуть всё объявлять как DependencyProperty...
в общем, буду делать по-правильному ))

а есть ли какой-то путь объявить DependencyProperty покороче? Сейчас всё вываливается в такую конструкцию:
        public static DependencyProperty SelectMethodProperty = DependencyProperty.Register(
            "SelectMethod",
            typeof(string),
            typeof(ListSourceConfig),
            new FrameworkPropertyMetadata() {
                DefaultValue = null
            });
        public string SelectMethod {
            get { return (string)GetValue(SelectMethodProperty); }
            set { SetValue(SelectMethodProperty, value); }
        }

и в ней надо очень много чего "не забыть подправить" после каждого копипаста. Что напрягает.
всю ночь не ем, весь день не сплю — устаю
Re[3]: [WPF] binding подсвойств
От: Neco  
Дата: 03.08.11 08:37
Оценка:
Здравствуйте, Neco, Вы писали:

N>а есть ли какой-то путь объявить DependencyProperty покороче? Сейчас всё вываливается в такую конструкцию:

пока обошёлся сниппетом (http://blog.davidsandor.com/post/2009/07/17/Code-Snippet-for-Dependency-Property-(WPFSL).aspx)
всю ночь не ем, весь день не сплю — устаю
Re[3]: [WPF] binding подсвойств
От: MxMsk Португалия  
Дата: 03.08.11 10:39
Оценка:
Здравствуйте, Neco, Вы писали:

N>собственно громоздкость второго (правильного варианта) для меня выражается в том, что реализация Freezable склоняет к тому, чтобы иметь все свойства как DependencyProperty — чего я собственно собирался избежать, поскольку привязка мне нужна будет к одному-двум свойствам.

N>Однако, раз взялся за гуж... вероятно надо привыкнуть всё объявлять как DependencyProperty...
N>в общем, буду делать по-правильному ))
Вполне можно избежать. Никто не обязывает делать все свойства через DependencyProperty. Можешь сделать только те, что требуется, а остальные — обычными. Просто нужно соблюдать некоторые правила, о которых написано здесь, в самом конце, в разделе Creating Your Own Freezable Class.

N>а есть ли какой-то путь объявить DependencyProperty покороче? Сейчас всё вываливается в такую конструкцию:

К сожалению, в C# только так. Для Nemerle есть макросы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.