【问题标题】:Binding problems using MVVM with WPF将 MVVM 与 WPF 结合使用的问题
【发布时间】:2016-04-10 15:03:06
【问题描述】:

我是 C# 新手。 我在绑定方面遇到了麻烦。我将代码示例留在这里,希望您能帮我找到麻烦。

好友视图

<UserControl x:Class="WpfWHERE.View.FriendsView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfWHERE.View"
         xmlns:ViewModel="clr-namespace:WpfWHERE.ViewModel"
         xmlns:data = "clr-namespace:WpfWHERE.Model"
         mc:Ignorable="d" 
         d:DesignHeight="600" d:DesignWidth="800">
<UserControl.DataContext>
    <ViewModel:FriendsViewModel/>
</UserControl.DataContext>
<UserControl.Resources><DataGrid x:Key="friendsList" AutoGenerateColumns="false" ItemsSource = "{Binding Student}">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Name" Width="150">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox x:Name="cbName" SelectedItem="{Binding Path=FullName, Mode=OneWay}" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" DisplayMemberPath="Name">
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

FriendsViewModel

public class FriendsViewModel:AViewModel
{
    #region fields
    public DelegateCommand DeleteCommand { get; set; }
    #endregion fields

    #region constructors
    public FriendsViewModel()
    {
        LoadStudents();
        DeleteCommand = new DelegateCommand(OnDelete, CanDelete);
    }
    #endregion constructors
    public ObservableCollection<Student> Students
    {
        get;
        set;
    }

    public void LoadStudents()
    {
        ObservableCollection<Student> students = new ObservableCollection<Student>();

        students.Add(new Student { FirstName = "Mark", LastName = "Allain" ,Place = "Home"});
        students.Add(new Student { FirstName = "Allen", LastName = "Brown", Place = "China" });
        students.Add(new Student { FirstName = "Linda", LastName = "Hamerski", Place = "Je" });

        Students = students;
    }

    private Student _selectedStudent;

    public Student SelectedStudent
    {
        get
        {
            return _selectedStudent;
        }

        set
        {
            _selectedStudent = value;
            DeleteCommand.RaiseCanExecuteChanged();
        }
    }

    private void OnDelete()
    {
        Students.Remove(SelectedStudent);
    }

    private bool CanDelete()
    {
        return SelectedStudent != null;
    }
}

学生

public class StudentModel { }

public class Student : INotifyPropertyChanged
{
    private string firstName;
    private string lastName;
    private string place;

    public string FirstName
    {
        get { return firstName; }

        set
        {
            if (firstName != value)
            {
                firstName = value;
                RaisePropertyChanged("FirstName");
                RaisePropertyChanged("FullName");
            }
        }
    }

    public string LastName
    {
        get { return lastName; }

        set
        {
            if (lastName != value)
            {
                lastName = value;
                RaisePropertyChanged("LastName");
                RaisePropertyChanged("FullName");
            }
        }
    }
    public string Place
    {
        get { return place; }

        set
        {
            if (place != value)
            {
                place = value;
                RaisePropertyChanged("Place");
            }
        }
    }

    public string FullName
    {
        get
        {
            return firstName + " " + lastName;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

我真的不知道自己做错了什么,我在谷歌上搜索了一下,但无法正常工作。我希望你能分享知识并帮助我。

最好的问候,

【问题讨论】:

  • 跳过你甚至没有告诉问题是什么的事实,你将friendList绑定到一个名为Student的属性,它......不存在。
  • 学生是我的模特。我正在尝试绑定它。还在学习这个 MVVM 架构...
  • ItemsSource 应该设置为您的收藏。将其更改为ItemsSource = "{Binding Students}"(即您的集合的属性名称)
  • @Tone 仍然不起作用i.imgur.com/iNiNiQl.png
  • 这是您的学生班级的名称,这意味着它正确地将项目绑定到您的 DataGrid,但它不知道如何显示它们。我真的不明白您要在 DataGrid 中显示什么,看起来您正在创建一个学生网格(每行 1 行),而且每一行都有一个包含完整学生列表的 ComboBox。这就是你想要做的吗?

标签: c# wpf mvvm view binding


【解决方案1】:

注意 cmets 中的 2 个变化

a) 使用ItemsSource = "{Binding Students} 代替ItemsSource = "{Binding Student}

b) 使用语法 &lt;TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" &gt;&lt;/TextBlock&gt; 的 TextBlock

您的FriendsView 的以下修改代码应该会给出所需的DataGrid 结果。经过测试并最终显示一个 DataGrid,其中有一列显示 FullName

<UserControl x:Class="WpfWHERE.View.FriendsView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:WpfWHERE.View"
         xmlns:ViewModel="clr-namespace:WpfWHERE.ViewModel"
         xmlns:data = "clr-namespace:WpfWHERE.Model"
         mc:Ignorable="d" 
         d:DesignHeight="600" d:DesignWidth="800">
    <UserControl.DataContext>
        <ViewModel:FriendsViewModel/>
    </UserControl.DataContext>
    <UserControl.Resources>
        <DataGrid x:Key="friendsList" AutoGenerateColumns="false" ItemsSource = "{Binding Students}">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Name" Width="150">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" ></TextBlock>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </UserControl.Resources>
    <ContentControl Content="{StaticResource friendsList}"/>
</UserControl>

请注意:

1) 我在 ContentControl 中显示了 DataGrid,因为我不确定你是如何显示它的。

2) 我不确定您的 AViewModel 中有什么,但它不应该影响结果

【讨论】:

  • 完美,有效。 AViewModel 是常见的 ViewModelBase。使用 Content 控件或将 DataGrid 直接放在 UserControl.Resources 之外有什么区别?
  • 如果你想在多个地方重用它,你通常会在UserControl.Resources 中使用x:Key 来定义事物。然后使用x:Key 将其称为StaticResource。如果您只使用一次,您可以将 DataGrid 放在 UserControl.Resources 之外并省略 x:Keyx:Key 在资源部分之外无效)。我只是把它放在ContentControl 中,所以我可以引用x:key 来匹配你的代码。
  • 很棒的解释。还有一件事,这个东西可以在其他视图中重用,比如 App.xml 中的样式模板,或者只是在那个视图中?
  • 如果要在多个视图中使用,请在Application.Resources 中定义App.xaml。其他资源块仅对控件是本地的(例如,UserControl.Resources 是该UserControl 的资源,StackPanel.Resources 是该StackPanel 的资源等)
  • 您在上面的 cmets 中提到您对我的回答赞不绝口。我不确定你的意思,但它没有接受或投票。如果您打算接受我的回答(您的选择),您可能需要查看Accepting Answers: How does it work?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-15
  • 1970-01-01
  • 2020-07-02
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多