【问题标题】:silverlight MVVM Viewmodel to view binding not workingsilverlight MVVM Viewmodel 视图绑定不起作用
【发布时间】:2010-12-07 19:09:59
【问题描述】:

我有一个真正简单的示例,它可以在没有视图模型的情况下很好地工作,因为我有一个项目 实现 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 事件正在被“监听”,因为 我的文本属性上的 Twoway 绑定。处理程序看起来像:

private void Button_Click(object sender, RoutedEventArgs e)
    {


        item.Name = "ted";
        item.Description = "adddress";


    }

所以当然这会改变 UI(我说这是一个非常简单的示例) 现在我介绍一个 Viewmodel 并且对简单模型的更改不会反映为 没有人在监听 propertychanged。

我将视图中的数据上下文设置为视图模型,实际上这是视图中唯一的代码行:

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"));被叫但没有人 聆听,因此不会进行任何更改。

我试图让这个例子真正简单,有些人会说太简单了,但我只是想 知道为什么绑定不起作用。我可以从视图拉到视图模型,但我需要 能够做相反的事情。我想知道我错过了什么。

【问题讨论】:

  • 我想我猜对了您的问题,但如果您另外包含 XAML 数据绑定代码,问题会更清楚。

标签: silverlight mvvm binding


【解决方案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="{Binding myitem > 在以下 XAML 中设置数据上下文:

 - <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 解决方案。不知道为什么我需要执行此步骤,但它似乎有效

【讨论】:

    【解决方案2】:

    您正在绑定到没有公开属性的 MyViewModel 实例。尝试制作并绑定到公共 MyViewModel.Item 属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-31
      • 2013-09-26
      • 2012-03-26
      • 2016-08-15
      • 2012-01-17
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多