WPF Связывают с участником класса в коде позади

Довольно простой вопрос, но, может казаться, не находит полный ответ на здесь...

Я должен связать с данными в 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;
  }
}

Что я имею, теперь не работает, что я делаю неправильно?

30
задан jaws 2 March 2010 в 21:42
поделиться

3 ответа

Путь должен соответствовать источнику (Source, DataContext, RelativeSource, ElementName). ElementName можно использовать только для ссылки на элементы, объявленные в XAML, по их x: Name. Вместо этого попробуйте указать на свое окно в качестве источника:

IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=RecordProp.IsViewChecked}"
27
ответ дан 27 November 2019 в 23:33
поделиться

Я вижу, что имя класса вашего окна - 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 свойством (если вы не реализуете уведомление об изменениях).

30
ответ дан 27 November 2019 в 23:33
поделиться

Data Binding не работает с приватными полями. Оно предназначено для публичных свойств. Попробуйте раскрыть значение _record публично и привязать его к этому значению.

Ссылка - http://msdn.microsoft.com/en-us/library/ms743643.aspx

3
ответ дан 27 November 2019 в 23:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: