我想綁定一個可觀察集合到用戶控件,但它沒有得到更新用戶更改,但它更新時通過代碼更改用戶控件。以下是我嘗試的一個例子。它可能有點長,但它正在工作,所以你可以複製和粘貼代碼。可觀察的集合沒有得到更新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 } }
- 窗口1。 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>
- Window1.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; 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我的用戶控件顯示的數據爲 「吉姆」。現在,當我改變文本說「約翰」,點擊更新,消息框仍然顯示「吉姆」,這意味着可觀察集合沒有得到更新。當我點擊更改按鈕時,用戶控件將數據更改爲「湯姆」。現在當我點擊更新按鈕時,Messagebox顯示「Tom」。任何人都可以告訴我如何通過更改用戶控件中的數據而不是通過代碼來實現可觀察集合的更新?
IT WORKED .. !!!!夢幻托馬斯.. !!!上帝,我一整天都在做這件事。太好了..只需要改變一下Text binding,你可以在你的答案中改變它,以便其他人可以使用它,也就是說,Mode = TwoWay缺失,這給了我一個構建錯誤,例如 Text =「{ Binding Path = Text,Mode = TwoWay,RelativeSource = {RelativeSource Mode = FindAncestor, AncestorType = {x:Type local:UCTextBox}}}「 – samar 2010-08-19 13:13:19
TextBox.Text默認爲雙向綁定,因此您不必製作它明確。無論如何,它不應該給你一個構建錯誤...這很奇怪 – 2010-08-19 13:20:51
哦,是這樣.. !!!但是,它確實給了我一個構建錯誤。 – samar 2010-08-20 05:55:39