带有ListView的TextBox使用Mvvm进行两次绑定

时间:2016-06-24 06:33:07

标签: c# wpf mvvm

   <Stackpanel>
       <TextBox x:Name="txtid" Width="90" Text={Binding Name} Height="25"/>
       <TextBox x:Name="txtname" Width="90" Text={Binding Age} Height="25" Margin="0 10 0 10"/> 
       <Button Command={Binding AddCommand} Content="Add"/>
       <ListView ItemsSource={Binding StudentList}/>
    </Stackpanel> 

视图模型

public class StudentViewModel : INotifyPropertyChanged
{

public StudentViewModel()
{
    _studentList = new ObservableCollection<StudentDetails>();
    LoadCommand();
}


private ObservableCollection<StudentDetails> _studentList;
public ObservableCollection<StudentDetails> StudentList
{
    get { return _studentList; }
    set
    {
        _studentList = value;
         OnPropertyChanged("StudentList");
    }
}

public StudentDetails SelectedItems { get; set; }

private string _name;
private int _age;
public string Name 
{ 
     get { return _name;}
     set { _name = value; OnPropertyChanged("Name")}
}
public string Age
{ 
     get { return _age;}
     set { _age = value; OnPropertyChanged("Age")}
}

public ICommand AddCommand { get; set; }


public void LoadCommand()
{
    AddCommand = new CustomCommand(Add, CanAdd);
}

private bool CanAdd(object obj)
{
    return true;
}

private void Add(object obj)
{
    StudentList.Add(new StudentDetails { Name = Name, Age = Age });

}}

模型

   public class StudentDetails : INotifyPropertyChanged
   {
      private string _name;
      private int _age;
      public string Name 
     { 
         get { return _name;}
         set { _name = value; OnPropertyChanged("Name")}
      }
     public string Age
     { 
         get { return _age;}
         set { _age = value; OnPropertyChanged("Age")}
     }}

我有两个文本框和上面的列表视图。如何使用MVVM进行双向绑定?这意味着输入的文本框值应添加到列表视图中,如果我选择列表视图中的值,则所选值应绑定到同一文本框,以便我可以更新值。怎么做??

2 个答案:

答案 0 :(得分:0)

我试过运行你的代码。它有很多错误。无论如何,根据您的问题,我认为您希望拥有列表视图,当用户选择特定列表项时,相应的年龄和名称将显示在文本框中,如果用户想要更新数据,则需要将其添加到列表中。首先使用绑定到类文件属性的数据模板创建列表视图。

现在还创建一个StudentDetails对象,并将列表视图的 SelectedItem 绑定到该对象。 当用户选择列表项时,您会收到 SelectionChanged 事件。在此期间更新2个文本框的属性,以在其中显示所选列表项数据。

现在,在添加按钮事件处理程序中,更新相应所选项的列表数据。确保将listitemssource绑定到 ObservableCollection

答案 1 :(得分:0)

我会为个别学生和学生列表提供不同的视图模型。 NameAge属性实际上不属于列表。

我使用MVVM Light语法作为示例:

<强> StudentViewModel

public class StudentViewModel : ViewModelBase
{
    private string _name;
    private int _age;
    public string Name
    {
        get { return _name; }
        set { Set<string>(ref _name, value); }
    }
    public int Age
    {
        get { return _age; }
        set { Set<int>(ref _age, value); }
    }
}

<强> StudentView.xaml

<UserControl x:Class="MasterDetailExample.Views.StudentView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:local="clr-namespace:MasterDetailExample.Views"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:vm="clr-namespace:MasterDetailExample.ViewModel"
         d:DesignHeight="300"
         d:DesignWidth="300"
         mc:Ignorable="d">

<WrapPanel HorizontalAlignment="Center" VerticalAlignment="Top">
    <TextBlock Text="Name: "/>
    <TextBox Text="{Binding Name}" Width="150"/>
    <TextBlock Text="Age: "/>
    <TextBox Text="{Binding Age}" Width="20"/>
</WrapPanel>
</UserControl>

现在 StudentsViewModel 代表学生列表:

public class StudentsViewModel : ViewModelBase
{
    private ObservableCollection<StudentViewModel> _studentList;
    private StudentViewModel _selectedStudent;

    public StudentsViewModel()
    {
        StudentList = new ObservableCollection<StudentViewModel>();

        StudentList.Add(new StudentViewModel { Name = "Joe", Age = 21 });
        StudentList.Add(new StudentViewModel { Name = "Jane", Age = 19 });
    }

    public ObservableCollection<StudentViewModel> StudentList
    {
        get { return _studentList; }
        private set { _studentList = value; }
    }

    public StudentViewModel SelectedStudent
    {
        get { return _selectedStudent; } 
        set { Set<StudentViewModel>(ref _selectedStudent, value); }
    }
}

**列表视图,StudentsView **

<UserControl x:Class="MasterDetailExample.Views.StudentsView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:views="clr-namespace:MasterDetailExample.Views"
         xmlns:vm="clr-namespace:MasterDetailExample.ViewModel"
         d:DesignHeight="300"
         d:DesignWidth="500"
         mc:Ignorable="d">
<UserControl.Resources>
    <vm:StudentsViewModel x:Key="StudentsVm" />
</UserControl.Resources>

<DockPanel DataContext="{StaticResource StudentsVm}">
    <ListView DockPanel.Dock="Left" Width="100" ItemsSource="{Binding StudentList}" SelectedItem="{Binding SelectedStudent}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Separator />
    <views:StudentView DockPanel.Dock="Right" DataContext="{Binding SelectedStudent}"/>
</DockPanel>
</UserControl>

直接设置DataContext的气味,

        <views:StudentView DockPanel.Dock="Right" DataContext="{Binding SelectedStudent}"/>

在更复杂的示例中,您可以为SelectedStudent创建DependencyProperty,或者实现一些消息传递逻辑以在不同的视图模型之间进行通信。