我有一个非常简单的例子,没有视图模型,因为我有一个Item 实现iNotifyPropertyChanged的类:
public class Item : INotifyPropertyChanged
{
private string _name;
private string _desc;
public string Name
{
get
{ return _name; }
set
{
if (_name == value)
return;
_name = value;
this.OnPropertyChanged(new PropertyChangedEventArgs("Name"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
public Item()
{
}
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, e);
}
}
这是一个简单的例子,我有以下代码:
public MainPage()
{
InitializeComponent();
item = new Item() { Name = "john", Description = "this is my name" };
LayoutRoot.DataContext = item;
}
如果我有一个在后面的代码中调用命令处理程序的按钮,我会看到更改 由于 propertychanged 事件正在被“监听”,因此对于简单的用户界面 我的text属性上的 Twoway 绑定。处理程序看起来像:
private void Button_Click(object sender, RoutedEventArgs e)
{
item.Name = "ted";
item.Description = "adddress";
}
所以当然这会改变UI(我说这是一个很简单的例子) 现在我介绍一个Viewmodel,对简单模型的更改不会反映为 没有人听财产改变。
我将视图中的datacontext设置为viewmodel,实际上这是视图中唯一的代码行:
LayoutRoot.DataContext = new MyViewModel();
现在我的Viewmodel看起来像:
public class MyViewModel
{
Item item = null;
public ICommand ChangeCommand { get; private set; }
public MyViewModel()
{
item = new Item() { Name = "john", Description = "jjjj" };
ChangeCommand = new DelegateCommand<string>(OnChange);
}
private void OnChange(string title)
{
item.Name = "bill";
}
注意: 我使用模式和实践命令将事件从XAML触发到Viewmodel 这很好用
我的处理程序再次更改了item.name,这导致调用setter和 this.OnPropertyChanged(new PropertyChangedEventArgs(“Name”));被召唤但没有人 听,所以不做任何改变。
我试图让这个例子变得简单,有些人会说太简单但我只是想 知道为什么绑定不起作用。我可以从视图拉到viewmodel但我需要 能够做到相反。我想知道我错过了什么点。
答案 0 :(得分:1)
实际上你似乎是在正确的轨道上,因为我注意到同样的事情,并改变了代码看起来像:
private Item _item;
public ICommand ChangeCommand { get; private set; }
public MyViewModel()
{
myitem = new Item() { Name = "john", Description = "jjjj" };
ChangeCommand = new DelegateCommand<string>(OnChange);
}
private void OnChange(string title)
{
_item.Name = "bill";
// SelectedItem = _item;
}
public Item myitem
{
get{return _item;}
set
{
_item = value;
RaisePropertyChanged(new PropertyChangedEventArgs("myitem"));
}
}
但我的字段仍未填写,直到我在我的文本字段周围放置一个网格,并通过Grid DataContext =“{绑定myitem&gt;”在以下XAML中设置datacontext:
- <UserControl
x:Class="BindingStart.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewmodel="clr-namespace:BindingStart"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Commands="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"
mc:Ignorable="d" d:DesignWidth="640"
d:DesignHeight="480"
>
<UserControl.Resources>
<viewmodel:MyViewModel x:Key="ViewModel" />
</UserControl.Resources> <Grid x:Name="LayoutRoot"
DataContext="{StaticResource
ViewModel}">
<StackPanel>
<Grid DataContext="{Binding myitem}">
<Grid.RowDefinitions>
<RowDefinition Height="22" />
<RowDefinition Height="22" />
<RowDefinition Height="22" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="300" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0"
Foreground="Black">SupplierName</TextBlock>
<TextBox x:Name="SName" Grid.Row="0" Grid.Column="1 "
IsReadOnly="True" Text="{Binding
Name, Mode=TwoWay}" />
现在我可以在代码中设置上下文,但我有点像XAML解决方案。不知道为什么我需要这样做,但它似乎工作
答案 1 :(得分:0)
您绑定到MyViewModel的实例,该实例没有公开的属性。尝试制作并绑定到公共MyViewModel.Item属性。