2010-08-19 1 views
2

관찰 가능 컬렉션을 사용자 정의 컨트롤에 바인딩하려고하지만 사용자 변경시 업데이트되지 않지만 사용자 정의 컨트롤이 코드를 통해 변경 될 때 업데이트 중입니다. 다음은 내가 시도한 예입니다. 조금 오래 될 수도 있지만 코드를 복사하여 붙여 넣을 수 있도록 작업 중입니다.관찰 가능 컬렉션이 UI 변경시 업데이트되지 않음

게시물 끝에있는 질문을 참조하십시오.

--Customer.cs

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.ComponentModel; 

namespace TestMVVM 
{ 
    class Customer : INotifyPropertyChanged 
    { 
     private string firstName; 
     private string lastName; 

     public string FirstName 
     { 
      get { return firstName; } 
      set 
      { 
       if (firstName != value) 
       { 
        firstName = value; 
        RaisePropertyChanged("FirstName"); 

       } 
      } 
     } 

     public string LastName 
     { 
      get { return lastName; } 
      set 
      { 
       if (lastName != value) 
       { 
        lastName = value; 
        RaisePropertyChanged("LastName"); 
       } 
      } 
     } 

     #region PropertChanged Block 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChanged(string property) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, 
new PropertyChangedEventArgs(property)); 
      } 
     } 
     #endregion 
    } 
} 

--UCTextBox.xaml

<UserControl x:Class="TestMVVM.UCTextBox" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="40" Width="200"> 
<Grid> 
    <TextBox Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="txtTextControl" 
      VerticalAlignment="Top" Width="120" /> 
</Grid> 

--UCTextBox.xaml.cs

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 

namespace TestMVVM 
{ 
    /// 
    /// Interaction logic for UCTextBox.xaml 
    /// 
    public partial class UCTextBox : UserControl, INotifyPropertyChanged 
    { 
     public UCTextBox() 
     { 
      InitializeComponent(); 
     } 

     public static readonly DependencyProperty TextProperty = 
     DependencyProperty.Register("Text", typeof(string), typeof(UCTextBox), 
     new UIPropertyMetadata(string.Empty, new PropertyChangedCallback(textChangedCallBack))); 

     static void textChangedCallBack(DependencyObject property, DependencyPropertyChangedEventArgs args) 
     { 
      UCTextBox pasTextBox = (UCTextBox)property; 
      pasTextBox.txtTextControl.Text = (string)args.NewValue; 
     } 

     public string Text 
     { 
      get 
      { 
       return (string)GetValue(TextProperty); 
      } 
      set 
      { 
       SetValue(TextProperty, value); 
       NotifyPropertyChanged("Text"); 
      } 
     } 

     private void NotifyPropertyChanged(String info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 

     #endregion 
    } 
} 

- 번째 윈도. xaml

<Window x:Class="TestMVVM.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TestMVVM" 
Title="Window1" Height="300" Width="300"> 
<Grid> 
    <local:UCTextBox x:Name="txtUC" /> 
    <Button Height="23" HorizontalAlignment="Left" Margin="39,0,0,82" 
      Name="btnUpdate" VerticalAlignment="Bottom" Width="75" Click="btnUpdate_Click">Update</Button> 
    <Button Height="23" Margin="120,0,83,82" Name="btnChange" VerticalAlignment="Bottom" Click="btnChange_Click">Change</Button> 
</Grid> 

-

 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Collections.ObjectModel; 

namespace TestMVVM 
{ 
    /// 
    /// Interaction logic for Window1.xaml 
    /// 
    public partial class Window1 : Window 
    { 
     CustomerHeaderViewModel customerHeaderViewModel = null; 
     public Window1() 
     { 
      InitializeComponent(); 

      customerHeaderViewModel = new CustomerHeaderViewModel(); 
      customerHeaderViewModel.LoadCustomers(); 

      txtUC.DataContext = customerHeaderViewModel.Customers[0]; 

      Binding binding = new Binding(); 
      binding.Source = customerHeaderViewModel.Customers[0]; 
      binding.Path = new System.Windows.PropertyPath("FirstName"); 
      binding.Mode = BindingMode.TwoWay; 

      binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 

      txtUC.SetBinding(UCTextBox.TextProperty, binding); 
     } 

     private void btnUpdate_Click(object sender, RoutedEventArgs e) 
     { 
      MessageBox.Show(customerHeaderViewModel.Customers[0].FirstName); 
     } 

     private void btnChange_Click(object sender, RoutedEventArgs e) 
     { 
      txtUC.Text = "Tom"; 
     } 
    } 

    class CustomerHeaderViewModel 
    { 
     public ObservableCollection Customers { get; set; } 

     public void LoadCustomers() 
     { 
      ObservableCollection customers = new ObservableCollection(); 

      customers.Add(new Customer { FirstName = "Jim", LastName = "Smith", NumberOfContracts = 23 }); 

      Customers = customers; 
     } 
    } 
} 

내가 Window1.xaml 내 사용자 정의 컨트롤 "짐"로 데이터를 보여줍니다 실행 Window1.xaml.cs

. 이제 "John"이라고 말한 텍스트를 변경하고 Update를 클릭하면 messagebox에 "Jim"이 표시되어 관찰 가능한 컬렉션이 업데이트되지 않음을 의미합니다. 변경 버튼을 클릭하면 사용자 컨트롤이 데이터를 "Tom"으로 변경합니다. 이제 Update 버튼을 클릭하면 Messagebox에 "Tom"이 표시됩니다. 누구든지 코드를 통해보다는 사용자 정의 컨트롤에서 데이터를 변경하여 관찰 가능한 컬렉션의 업데이트를 수행하는 방법을 알려주시겠습니까?

답변

2

사용자가 txtTextControl.TextChanged 이벤트를 처리하지 않아서 해당 사용자의 Text 종속성 속성이 업데이트되지 않습니다.

어쨌든, 당신이 수동으로 DependencyPropertyChangedCallback 및 이벤트 핸들러에 처리 할 필요가 없습니다, 당신은 단지 txtTextControl.TextText 종속성 속성에 바인딩 할 수 있습니다 :

<TextBox Height="23" HorizontalAlignment="Left" Margin="10,10,0,0" Name="txtTextControl" 
     VerticalAlignment="Top" Width="120" 
     Text="{Binding Path=Text, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:UCTextBox}}}"/> 
+0

IT WORKED .. !!!! 환상적인 토마스 .. !!! 나는 하루 종일이 일을하고 있었다. Too Good man .. 다른 사람들이 그것을 사용할 수 있도록 당신의 답을 바꿀 수있는 Text binding에서 단지 1 번 변경. 즉, Mode = TwoWay가 없어서 빌드 오류가 발생했습니다. Text = "{ 바인딩 경로 = 텍스트, 모드 = 양방향은 RelativeSource = {RelativeSource 모드 = FindAncestor는 AncestorType = {X : 유형 지역 : UCTextBox}} 당신이 할 필요가 없습니다 있도록}는 " – samar

+0

TextBox.Text는 기본적으로 양방향 바인딩 그것은 명백하다. 어쨌든 빌드 오류가 발생해서는 안됩니다 ... 이상한데 –

+0

오, 그렇게 .. !!! 하지만 그래, 나에게 빌드 오류를주지 않았다. – samar

0

피 감시 수집, 관찰자 ​​컬렉션을 만 . 단일 항목의 필드가 변경된 경우가 아니라 항목이 추가되거나 삭제 될 때 알림을 받게됩니다. 그것은 완전히 다른 것입니다. Thomas Levesque가 말했듯이, 올바른 속성을 묶는 것만으로도 충분합니다.