Подтвердить что ты не робот

WPF Привязать к члену класса в коде

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

Мне нужно привязать databind в 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;
  }
}

То, что у меня сейчас, не работает, что я делаю неправильно?

4b9b3361

Ответ 1

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

IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=RecordProp.IsViewChecked}"

Ответ 2

То, что я вижу здесь, это то, что ваше имя класса окна Main, вы добавили к нему свойство RecordProp и теперь пытаетесь привязать его к свойству IsChecked элемент с именем RecordProp. Я думаю, вы немного смущены тем, как работают имена.

Добавление атрибута x:Name к элементу XAML создает поле в классе окна с этим именем. Это позволяет вам ссылаться на именованные элементы в вашем коде, и это, вероятно, привело вас к мысли, что привязка может сделать то же самое.

Но это не так, как привязка находит именованные элементы. Атрибут x:Name также принимает объект, который элемент XAML создает и регистрирует его под этим именем в окне имен. (См. статья MSDN об именах имен XAML.). Что связывает поиск разрешенных имен элементов. Поскольку вы никогда не добавляете объект в указатель, установка свойства 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". Поскольку это динамический ресурс, если что-то внешнее к окну устанавливает свойство window RecordProp, привязки к нему будут обновляться - это то, чего не произойдет, если вы просто сделаете свойство RecordProp (если вы не внесете изменения в уведомление об изменении).

Ответ 3

Я считаю, что у меня более простой ответ, чем те, которые были указаны до сих пор. Просто добавьте это в объявление окна (самый первый тег) в XAML:

x:Name="this"

Затем вы можете привязать данные следующим образом:

<customcontrol Name="View" IsChecked="{Binding ElementName=this, Path=RecordProp.IsViewChecked}" />

Я проверил, что С# жалуется, что уже есть "это", и это не так, я думаю, потому что они оба относятся к одному и тому же объекту.

Это решение, которое я использовал, когда столкнулся с той же проблемой, и нашел, что это очень интуитивно понятно.

Ответ 4

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

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