silverlight MVVM Viewmodel查看绑定​​无法正常工作

时间:2009-10-18 15:44:55

标签: silverlight mvvm binding

我有一个非常简单的例子,没有视图模型,因为我有一个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但我需要 能够做到相反。我想知道我错过了什么点。

2 个答案:

答案 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属性。