Как сделать так, чтобы свойства зависимостей моего пользовательского элемента управления WPF обновляли мою модель представления? - PullRequest
15 голосов
/ 08 октября 2010

Я пытаюсь создать пользовательский элемент управления со свойствами зависимости для привязки.Внутренне у меня есть ComboBox, который связан с этими же свойствами, но привязка работает только в одном направлении.ComboBox заполняется из ItemsSource, но SelectedItem не обновляется обратно к модели представления, к которой я привязан.

Упрощенный пример:

Это представлениемодель для привязки с пользовательским элементом управления:

public class PeopleViewModel : INotifyPropertyChanged
{
    public PeopleViewModel()
    {
        People = new List<string>( new [] {"John", "Alfred","Dave"});
        SelectedPerson = People.FirstOrDefault();
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private IEnumerable<string> _people;
    public IEnumerable<string> People 
    { 
        get { return _people; } 
        set
        {
            _people = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("People"));
            }
        }
    }

    private string _selectedPerson;
    public string SelectedPerson 
    {
        get { return _selectedPerson; }
        set 
        { 
            _selectedPerson = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("SelectedPerson"));
            }
        } 
    }
}

Это пользовательский элемент управления:

<UserControl x:Class="PeopleControlTest.PeopleControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" d:DesignHeight="56" d:DesignWidth="637">
<StackPanel >
    <ComboBox Margin="11"
              ItemsSource="{Binding BoundPeople, RelativeSource={RelativeSource AncestorType=UserControl}}"
              SelectedItem="{Binding BoundSelectedPerson, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</StackPanel>

с кодом позади

public partial class PeopleControl : UserControl
{
    public PeopleControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty BoundPeopleProperty =
        DependencyProperty.Register("BoundPeople", typeof(IEnumerable<string>), typeof(PeopleControl), new UIPropertyMetadata(null));

    public static readonly DependencyProperty BoundSelectedPersonProperty =
        DependencyProperty.Register("BoundSelectedPerson", typeof(string), typeof(PeopleControl), new UIPropertyMetadata(""));

    public IEnumerable<string> BoundPeople
    {
        get { return (IEnumerable<string>)GetValue(BoundPeopleProperty); }
        set { SetValue(BoundPeopleProperty, value); }
    }

    public string BoundSelectedPerson
    {
        get { return (string)GetValue(BoundSelectedPersonProperty); }
        set { SetValue(BoundSelectedPersonProperty, value); }
    }
}

И вот как я связываю пользовательский элемент управления в главном окне (с контекстом данных Windows, установленным для экземпляра модели представления)

<Window x:Class="PeopleControlTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:controls="clr-namespace:PeopleControlTest"
    Title="MainWindow" Height="350" Width="525">
    <Grid>
        <controls:PeopleControl 
            BoundPeople="{Binding People}" 
            BoundSelectedPerson="{Binding SelectedPerson}"/>
    </Grid>
</Window>

Поле со списком в пользовательском элементе управления заполняется именами, но когда явыберите другое имя, которое не будет обновлено до модели представления.Есть идеи, что мне здесь не хватает?

Спасибо!

1 Ответ

20 голосов
/ 08 октября 2010

По умолчанию некоторые свойства связываются двусторонне (включая SelectedItem), а ваши BoundSelectedPerson - нет.Вы можете установить режим привязки:

   <controls:PeopleControl 
            BoundPeople="{Binding People}" 
            BoundSelectedPerson="{Binding SelectedPerson, Mode=TwoWay}"/>

. Или вы можете сделать его двухсторонним по умолчанию, установив флаг на DependencyProperty:

    public static readonly DependencyProperty BoundSelectedPersonProperty =
        DependencyProperty.Register("BoundSelectedPerson", typeof(string), typeof(PeopleControl), new FrameworkPropertyMetadata("",FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...