Вопрос по wpf, checkbox – WPF Databinding CheckBox.IsChecked

7

Как бы я связал член IsChecked CheckBox с переменной члена в моей форме?

(Я понимаю, что могу получить к нему доступ напрямую, но я пытаюсь узнать о привязке данных и WPF)

Ниже моя неудачная попытка заставить это работать.

XAML:

<code><Window x:Class="MyProject.Form1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Title" Height="386" Width="563" WindowStyle="SingleBorderWindow">
<Grid>
    <CheckBox Name="checkBoxShowPending" 
              TabIndex="2" Margin="0,12,30,0" 
              Checked="checkBoxShowPending_CheckedChanged" 
              Height="17" Width="92" 
              VerticalAlignment="Top" HorizontalAlignment="Right" 
              Content="Show Pending" IsChecked="{Binding ShowPending}">
    </CheckBox>
</Grid>
</Window>
</code>

Код:

<code>namespace MyProject
{
    public partial class Form1 : Window
    {
        private ListViewColumnSorter lvwColumnSorter;

        public bool? ShowPending
        {
            get { return this.showPending; }
            set { this.showPending = value; }
        }

        private bool showPending = false;

        private void checkBoxShowPending_CheckedChanged(object sender, EventArgs e)
        {
            //checking showPending.Value here.  It's always false
        }
    }
}
</code>

Ваш Ответ

4   ответа
0

который вы хотите связать со свойством кода, вы можете указать его в качестве источника привязки черезRelativeSource как это:

<CheckBox ...
IsChecked="{Binding ShowPending, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">

Это может быть конец ответа. Но в целом у вас будет несколько элементов управления и вы захотите привязать их к различным свойствам вашего класса. В этом случае удобнее и удобнее использовать тот факт, чтоDataContext Свойство (которое является исходным объектом по умолчанию для привязки данных) наследуется через иерархию элементов управления, поэтому установка его на верхнем уровне сделает его доступным для всех дочерних элементов управления.

Там нет значения по умолчанию дляDataContext, но есть как минимум два способаDataContext свойство вашего элемента Window указывать на себя:

By setting DataContext = this in the code-behind constructor. This is very simple, but some might argue that it's not clear in the XAML where the DataContext is pointing. By setting the DataContext in XAML using DataBinding

Самый простой и, я думаю, самый элегантный способ установить DataContext на уровне Window / UserControl в XAML очень прост; просто добавьDataContext="{Binding RelativeSource={RelativeSource Self}}" на вашWindow элемент.RelativeSource Self просто означает «привязать непосредственно к объекту», который в данном случае являетсяWindow объект. ОтсутствиеPath свойство приводит к значению по умолчаниюPath, который является самим исходным объектом (то есть окном).

<Window x:Class="MyProject.Form1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <CheckBox ... 
            IsChecked="{Binding ShowPending}">
        </CheckBox>
    </Grid>
</Window>

Как только вы это сделали,DataContext свойство для всех дочерних элементов управления будетWindow класс, поэтому привязка данных к свойствам в вашем коде позади будет естественным.

Если по какой-либо причине вы не хотите устанавливатьDataContext в окне, но вы хотите установить его ниже иерархии управления, тогда вы можете сделать это, используяFindAncestor механизм. Например. если вы хотите установить его для элемента Grid и всех дочерних элементов Grid:

<Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
    <CheckBox ...
          IsChecked="{Binding ShowPending}">
    </CheckBox>
</Grid>

Вероятно, стоит отметить, что на данный момент мы достигли возможности привязать элемент управления пользовательского интерфейса к свойству класса code-behind и поддерживать это свойство code-behind в актуальном состоянии с изменения в элементе пользовательского интерфейса. Так что, если пользователь проверяет CheckBox,ShowPending свойство будет обновлено.

Но довольно часто вы также хотите, чтобы обратное было правдой; изменение свойства источника должно быть отражено в соответствующем изменении элемента управления пользовательского интерфейса. Вы можете увидеть это, добавив еще один элемент управления CheckBox к вашему окну, привязанный к тому жеShowPending имущество. Когда вы нажимаете один флажок, вы, вероятно, надеетесь или ожидаете, что другой флажок будет синхронизирован, но это не произойдет. Для достижения этого ваш класс code-behind должен либо (a) реализоватьINotifyPropertyChanged, (б) добавитьShowPendingChanged событие или (с) сделатьShowPending Свойство зависимости, Из 3 я предлагаю реализациюINotifyPropertryChanged в вашем коде позади является наиболее распространенным механизмом.

12
<Window ... Name="MyWindow">
  <Grid>
    <CheckBox ... IsChecked="{Binding ElementName=MyWindow, Path=ShowPending}"/>
  </Grid>
</Window>

<Window>и изменил привязку в вашем CheckBox. Вам нужно будет реализовать ShowPending какDependencyProperty а также, если вы хотите, чтобы он мог обновляться при изменении.

Если недвижимость находится вViewModel а неView сам, как бы вы сделали привязку?
При использовании ViewModel вы обычно устанавливаете свой DataContext в вашем View (или в XAML) на ViewModel и просто делаетеIsChecked="{Binding ShowPending}"
2

DependencyProperty может выглядеть как (создано с использованиемФрагменты Dr. WPF):

#region ShowPending

/// <summary>
/// ShowPending Dependency Property
/// </summary>
public static readonly DependencyProperty ShowPendingProperty =
    DependencyProperty.Register("ShowPending", typeof(bool), typeof(MainViewModel),
        new FrameworkPropertyMetadata((bool)false));

/// <summary>
/// Gets or sets the ShowPending property. This dependency property 
/// indicates ....
/// </summary>
public bool ShowPending
{
    get { return (bool)GetValue(ShowPendingProperty); }
    set { SetValue(ShowPendingProperty, value); }
}

#endregion
0

<Checkbox IsChecked="{Binding Path=ShowPending, Mode=TwoWay}"/>
Хотя для многих свойств по умолчанию используется OneWay, по умолчанию свойство IsChecked имеет значение TwoWay. УвидетьBinding Overview

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