Довольно простой вопрос, но, может казаться, не находит полный ответ на здесь...
Я должен связать с данными в xaml к свойству участника класса в codebehind.
<Window x:Class="Main">
<customcontrol Name="View" IsChecked="{Binding ElementName=RecordProp, Path=IsViewChecked}" />
...
Где код позади похож:
class Main
{
...
private Record _record;
public Record RecordProp
{
get { return _record; }
}
...
}
class Record
{
public bool IsViewChecked
{
get; set;
}
}
Что я имею, теперь не работает, что я делаю неправильно?
Путь должен соответствовать источнику (Source, DataContext, RelativeSource, ElementName). ElementName можно использовать только для ссылки на элементы, объявленные в XAML, по их x: Name. Вместо этого попробуйте указать на свое окно в качестве источника:
IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=RecordProp.IsViewChecked}"
Я вижу, что имя класса вашего окна - Main
, что вы добавили к нему свойство RecordProp
и что теперь вы пытаетесь привязаться к свойству IsChecked
элемента с именем RecordProp
. Мне кажется, вы немного запутались в том, как работают имена.
Добавление атрибута x:Name
к элементу XAML создает поле в классе окна с таким именем. Это позволяет вам ссылаться на именованные элементы в вашем коде, и, вероятно, это навело вас на мысль, что привязка может делать то же самое.
Но привязка не так находит именованные элементы. Атрибут x:Name
also берет объект, который создает элемент XAML, и регистрирует его под этим именем в области имен окна. (См. статью MSDN о XAML namescopes. ) Это то, на что смотрит binding для разрешения имен элементов. Поскольку вы никогда не добавляете объект в namescope, установка свойства ElementName
в привязке не найдет его.
Есть несколько вещей, которые вы могли бы сделать. Если вы действительно хотите привязаться к свойству окна, вы можете дать окну имя и привязаться к свойству, используя путь к свойству:
<Window x:Name="MainWindow" x:Class="Main">
...
<customcontrol Name="View" IsChecked="
{Binding ElementName=MainWindow,
Path=RecordProp.IsViewChecked}" />
Еще проще - просто установить контекст данных в конструкторе:
DataContext = this;
Сделав это, вы можете просто привязаться к свойству RecordProp
(и любому другому свойству окна) следующим образом:
<customControl Name="View" IsChecked={Binding RecordProp.IsChecked}/>
Конечно, это не будет работать, если вам нужно, чтобы контекст данных окна был установлен на что-то другое.
Другая возможность - реализовать свойство следующим образом:
public Record RecordProp
{
get { return (Record)Resources["RecordProp"]; }
set { Resources["RecordProp"] = value; }
}
Вы можете привязаться к нему, используя (например) Binding {DynamicResource RecordProp}, Path=IsChecked"
. Поскольку это динамический ресурс, если что-то внешнее по отношению к окну установит свойство RecordProp
окна, привязки к нему обновятся - чего не произойдет, если вы просто сделаете RecordProp
свойством (если вы не реализуете уведомление об изменениях).
Data Binding не работает с приватными полями. Оно предназначено для публичных свойств. Попробуйте раскрыть значение _record
публично и привязать его к этому значению.
Ссылка - http://msdn.microsoft.com/en-us/library/ms743643.aspx