C#中如何实现WPF联系人列表

发布时间:2021-12-01 09:14:24 作者:小新
来源:亿速云 阅读:306

C#中如何实现WPF联系人列表

目录

  1. 引言
  2. WPF基础
  3. 项目结构
  4. 数据模型
  5. 视图模型
  6. 用户界面
  7. 数据持久化
  8. 功能实现
  9. 测试与调试
  10. 总结

引言

在现代应用程序开发中,联系人列表是一个非常常见的功能。无论是通讯录、社交应用还是企业管理系统,联系人列表都是不可或缺的一部分。本文将详细介绍如何使用C#和WPF(Windows Presentation Foundation)来实现一个功能齐全的联系人列表应用程序。

WPF是微软推出的一种用于构建Windows桌面应用程序的UI框架。它提供了丰富的控件库、强大的数据绑定机制以及灵活的布局系统,使得开发者能够轻松创建出美观且功能强大的用户界面。

本文将从头开始,逐步引导您完成一个WPF联系人列表应用程序的开发。我们将涵盖从项目创建、数据模型设计、视图模型实现、用户界面设计到数据持久化和功能实现的各个方面。

WPF基础

WPF概述

WPF(Windows Presentation Foundation)是微软推出的一种用于构建Windows桌面应用程序的UI框架。它基于DirectX,提供了丰富的图形渲染能力,支持2D和3D图形、动画、多媒体等高级功能。WPF还引入了XAML(Extensible Application Markup Language)作为UI描述语言,使得界面设计更加直观和灵活。

XAML简介

XAML是一种基于XML的标记语言,用于定义WPF应用程序的用户界面。通过XAML,开发者可以声明式地定义UI元素、布局、样式、数据绑定等。XAML与C#代码分离,使得界面设计与业务逻辑分离,提高了代码的可维护性和可读性。

MVVM模式

MVVM(Model-View-ViewModel)是一种设计模式,广泛应用于WPF应用程序中。它将应用程序分为三个部分:

MVVM模式的核心思想是通过数据绑定将View和ViewModel解耦,使得UI逻辑与业务逻辑分离,提高了代码的可测试性和可维护性。

项目结构

创建WPF项目

首先,我们需要创建一个新的WPF项目。打开Visual Studio,选择“创建新项目”,然后选择“WPF应用程序”模板。为项目命名,例如“ContactListApp”,然后点击“创建”。

项目文件结构

创建项目后,您会看到以下文件结构:

数据模型

联系人模型

首先,我们需要定义一个联系人模型,用于表示联系人的基本信息。在项目中创建一个新的类文件,命名为Contact.cs,并定义以下属性:

public class Contact
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
    public string Address { get; set; }
}

数据绑定

WPF提供了强大的数据绑定机制,可以将UI元素与数据模型绑定在一起。通过数据绑定,我们可以实现数据的自动更新和同步。在XAML中,可以使用Binding语法将UI元素的属性与数据模型的属性绑定。

例如,将TextBoxText属性与ContactFirstName属性绑定:

<TextBox Text="{Binding FirstName}" />

视图模型

联系人视图模型

接下来,我们需要创建一个视图模型,用于管理联系人列表和UI逻辑。在项目中创建一个新的类文件,命名为ContactViewModel.cs,并定义以下属性和方法:

public class ContactViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Contact> _contacts;
    public ObservableCollection<Contact> Contacts
    {
        get { return _contacts; }
        set
        {
            _contacts = value;
            OnPropertyChanged(nameof(Contacts));
        }
    }

    public ContactViewModel()
    {
        Contacts = new ObservableCollection<Contact>();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

命令实现

在WPF中,命令(Command)用于处理用户操作,例如按钮点击。我们可以通过实现ICommand接口来定义自定义命令。在ContactViewModel中添加一个AddContactCommand,用于添加新联系人:

public class AddContactCommand : ICommand
{
    private readonly ContactViewModel _viewModel;

    public AddContactCommand(ContactViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _viewModel.Contacts.Add(new Contact());
    }

    public event EventHandler CanExecuteChanged;
}

ContactViewModel中初始化命令:

public ICommand AddContactCommand { get; }

public ContactViewModel()
{
    Contacts = new ObservableCollection<Contact>();
    AddContactCommand = new AddContactCommand(this);
}

用户界面

主窗口设计

在主窗口的XAML文件中,定义基本的布局和控件。我们可以使用Grid布局来组织UI元素:

<Window x:Class="ContactListApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Contact List" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Content="Add Contact" Command="{Binding AddContactCommand}" Margin="10"/>
        <ListView Grid.Row="1" ItemsSource="{Binding Contacts}" Margin="10">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}"/>
                    <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}"/>
                    <GridViewColumn Header="Email" DisplayMemberBinding="{Binding Email}"/>
                    <GridViewColumn Header="Phone Number" DisplayMemberBinding="{Binding PhoneNumber}"/>
                    <GridViewColumn Header="Address" DisplayMemberBinding="{Binding Address}"/>
                </GridView>
            </ListView.View>
        </ListView>
    </Grid>
</Window>

联系人列表设计

ListView中,我们使用GridView来显示联系人列表的详细信息。每一列对应一个联系人属性,通过DisplayMemberBinding将列与联系人属性绑定。

联系人详情设计

为了显示和编辑联系人详情,我们可以创建一个新的窗口或用户控件。在项目中创建一个新的用户控件,命名为ContactDetailView.xaml,并定义以下布局:

<UserControl x:Class="ContactListApp.ContactDetailView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:ContactListApp">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Label Content="First Name:" Grid.Row="0" Grid.Column="0"/>
        <TextBox Text="{Binding FirstName}" Grid.Row="0" Grid.Column="1" Margin="5"/>
        <Label Content="Last Name:" Grid.Row="1" Grid.Column="0"/>
        <TextBox Text="{Binding LastName}" Grid.Row="1" Grid.Column="1" Margin="5"/>
        <Label Content="Email:" Grid.Row="2" Grid.Column="0"/>
        <TextBox Text="{Binding Email}" Grid.Row="2" Grid.Column="1" Margin="5"/>
        <Label Content="Phone Number:" Grid.Row="3" Grid.Column="0"/>
        <TextBox Text="{Binding PhoneNumber}" Grid.Row="3" Grid.Column="1" Margin="5"/>
        <Label Content="Address:" Grid.Row="4" Grid.Column="0"/>
        <TextBox Text="{Binding Address}" Grid.Row="4" Grid.Column="1" Margin="5"/>
    </Grid>
</UserControl>

数据持久化

使用JSON文件

为了持久化联系人数据,我们可以使用JSON文件来存储和加载联系人列表。首先,安装Newtonsoft.Json库,这是一个流行的JSON序列化和反序列化库。

ContactViewModel中添加以下方法来加载和保存联系人数据:

public void LoadContacts(string filePath)
{
    if (File.Exists(filePath))
    {
        var json = File.ReadAllText(filePath);
        Contacts = JsonConvert.DeserializeObject<ObservableCollection<Contact>>(json);
    }
}

public void SaveContacts(string filePath)
{
    var json = JsonConvert.SerializeObject(Contacts);
    File.WriteAllText(filePath, json);
}

加载和保存数据

在应用程序启动时,加载联系人数据;在应用程序关闭时,保存联系人数据。可以在App.xaml.cs中处理这些逻辑:

public partial class App : Application
{
    private const string ContactsFilePath = "contacts.json";

    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        var mainWindow = new MainWindow();
        var viewModel = new ContactViewModel();
        viewModel.LoadContacts(ContactsFilePath);
        mainWindow.DataContext = viewModel;
        mainWindow.Show();
    }

    protected override void OnExit(ExitEventArgs e)
    {
        var viewModel = (ContactViewModel)MainWindow.DataContext;
        viewModel.SaveContacts(ContactsFilePath);

        base.OnExit(e);
    }
}

功能实现

添加联系人

ContactViewModel中,我们已经实现了AddContactCommand,用于添加新联系人。当用户点击“Add Contact”按钮时,会执行该命令,向联系人列表中添加一个新的联系人。

编辑联系人

为了实现编辑联系人功能,我们可以在ContactDetailView中绑定当前选中的联系人。在ContactViewModel中添加一个SelectedContact属性:

private Contact _selectedContact;
public Contact SelectedContact
{
    get { return _selectedContact; }
    set
    {
        _selectedContact = value;
        OnPropertyChanged(nameof(SelectedContact));
    }
}

MainWindow.xaml中,将ListViewSelectedItem属性与SelectedContact绑定:

<ListView Grid.Row="1" ItemsSource="{Binding Contacts}" SelectedItem="{Binding SelectedContact}" Margin="10">
    <!-- GridView columns -->
</ListView>

ContactDetailView中,将DataContext设置为SelectedContact

<UserControl DataContext="{Binding SelectedContact}">
    <!-- Contact detail controls -->
</UserControl>

删除联系人

为了实现删除联系人功能,我们可以在ContactViewModel中添加一个DeleteContactCommand

public class DeleteContactCommand : ICommand
{
    private readonly ContactViewModel _viewModel;

    public DeleteContactCommand(ContactViewModel viewModel)
    {
        _viewModel = viewModel;
    }

    public bool CanExecute(object parameter)
    {
        return _viewModel.SelectedContact != null;
    }

    public void Execute(object parameter)
    {
        _viewModel.Contacts.Remove(_viewModel.SelectedContact);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

ContactViewModel中初始化命令:

public ICommand DeleteContactCommand { get; }

public ContactViewModel()
{
    Contacts = new ObservableCollection<Contact>();
    AddContactCommand = new AddContactCommand(this);
    DeleteContactCommand = new DeleteContactCommand(this);
}

MainWindow.xaml中添加一个“Delete Contact”按钮,并将其与DeleteContactCommand绑定:

<Button Content="Delete Contact" Command="{Binding DeleteContactCommand}" Margin="10"/>

搜索联系人

为了实现搜索联系人功能,我们可以在ContactViewModel中添加一个SearchText属性和一个FilteredContacts属性:

private string _searchText;
public string SearchText
{
    get { return _searchText; }
    set
    {
        _searchText = value;
        OnPropertyChanged(nameof(SearchText));
        FilterContacts();
    }
}

private ObservableCollection<Contact> _filteredContacts;
public ObservableCollection<Contact> FilteredContacts
{
    get { return _filteredContacts; }
    set
    {
        _filteredContacts = value;
        OnPropertyChanged(nameof(FilteredContacts));
    }
}

private void FilterContacts()
{
    if (string.IsNullOrEmpty(SearchText))
    {
        FilteredContacts = new ObservableCollection<Contact>(Contacts);
    }
    else
    {
        FilteredContacts = new ObservableCollection<Contact>(
            Contacts.Where(c => c.FirstName.Contains(SearchText, StringComparison.OrdinalIgnoreCase) ||
                                 c.LastName.Contains(SearchText, StringComparison.OrdinalIgnoreCase)));
    }
}

MainWindow.xaml中添加一个TextBox用于输入搜索文本,并将ListViewItemsSource绑定到FilteredContacts

<TextBox Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" Margin="10"/>
<ListView Grid.Row="1" ItemsSource="{Binding FilteredContacts}" SelectedItem="{Binding SelectedContact}" Margin="10">
    <!-- GridView columns -->
</ListView>

测试与调试

单元测试

为了确保代码的正确性,我们可以编写单元测试来测试ContactViewModel中的逻辑。使用NUnitxUnit等测试框架,编写测试用例来验证添加、删除、搜索联系人等功能。

例如,测试添加联系人功能:

[Test]
public void AddContactCommand_AddsNewContact()
{
    var viewModel = new ContactViewModel();
    var initialCount = viewModel.Contacts.Count;

    viewModel.AddContactCommand.Execute(null);

    Assert.AreEqual(initialCount + 1, viewModel.Contacts.Count);
}

调试技巧

在WPF应用程序中,调试数据绑定问题可能会比较困难。可以使用PresentationTraceSources.TraceLevel来启用数据绑定的调试输出:

System.Diagnostics.PresentationTraceSources.DataBindingSource.Switch.Level = System.Diagnostics.SourceLevels.All;

此外,使用Visual Studio的调试工具,如断点、监视窗口、即时窗口等,可以帮助快速定位和解决问题。

总结

通过本文的详细讲解,我们实现了一个功能齐全的WPF联系人列表应用程序。我们从项目创建、数据模型设计、视图模型实现、用户界面设计到数据持久化和功能实现,逐步完成了整个开发过程。

WPF提供了强大的工具和机制,使得开发者能够轻松创建出美观且功能强大的桌面应用程序。通过MVVM模式,我们将UI逻辑与业务逻辑分离,提高了代码的可维护性和可测试性。

希望本文能够帮助您更好地理解WPF开发,并为您的项目提供有价值的参考。如果您有任何问题或建议,欢迎在评论区留言讨论。

推荐阅读:
  1. Exchange 隐藏联系人在地址列表中显示
  2. C# WPF 开发利器 集合

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

wpf

上一篇:Oracle的数据字典是什么

下一篇:ADO.NET OracleClient命名空间对象有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》