2010-10-07 45 views
14

Tôi đang cố gắng tạo điều khiển người dùng với các thuộc tính phụ thuộc để liên kết. Trong nội bộ tôi có một ComboBox được ràng buộc với các thuộc tính giống nhau, nhưng ràng buộc chỉ hoạt động theo một cách. Các ComboBox điền từ ItemsSource, nhưng SelectedItem không được cập nhật trở lại chế độ xem mô hình mà tôi đang ràng buộc.Làm cách nào để các thuộc tính phụ thuộc của WPF User Control cập nhật mô hình xem của tôi?

Một ví dụ đơn giản:

Đây là mô hình điểm để ràng buộc với các điều khiển người dùng:

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")); 
      } 
     } 
    } 
} 

này là kiểm soát tài khoản:

<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> 

với mã phía sau

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); } 
    } 
} 

Và đây là cách tôi ràng buộc điều khiển người dùng trong cửa sổ chính (với bối cảnh cửa sổ dữ liệu thiết lập để một thể hiện của viewmodel)

<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> 

Các combobox trong việc kiểm soát người dùng điền với tên, nhưng khi tôi chọn một tên khác, điều này sẽ không được cập nhật trở lại mô hình xem. Bất kỳ ý tưởng những gì tôi đang thiếu ở đây?

Cảm ơn!

Trả lời

19

Một số thuộc tính ràng buộc hai chiều theo mặc định (Bao gồm SelectedItem) nhưng không BoundSelectedPerson của bạn. Bạn có thể thiết lập các chế độ của các ràng buộc:

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

Hoặc bạn có thể làm cho nó TwoWay theo mặc định bằng cách thiết lập một lá cờ trên DependencyProperty:

public static readonly DependencyProperty BoundSelectedPersonProperty = 
     DependencyProperty.Register("BoundSelectedPerson", typeof(string), typeof(PeopleControl), new FrameworkPropertyMetadata("",FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)); 
+0

Tuyệt vời, cảm ơn bạn, mà làm việc !!! Vì lý do nào đó, tôi nghĩ rằng tôi muốn đọc rằng tất cả các DP làm việc theo hai chiều theo mặc định. Tôi đã sử dụng UIPropertyMetadata là tốt, mà trên đó tôi không thể tìm thấy tùy chọn đó. – Stefan

+0

_ (Giải pháp này là tốt. Tôi chỉ muốn thêm một lưu ý cho những người có thể có cùng một vấn đề tôi đã có và tìm đường đến đây trong khi tìm kiếm giải pháp.) _ Thuộc tính mà bạn liên kết với thuộc tính phụ thuộc của UserControl phải có một phương thức set(). – skst

Các vấn đề liên quan