WPF 面试题 + 参考答案,偏 C# 桌面端开发高频。

1. WPF 是什么?

答:

WPF 全称是 Windows Presentation Foundation,是微软推出的桌面 UI 框架。

它基于 .NET,使用 XAML 描述界面,使用 C# 编写逻辑。

WPF 的特点:

  • 支持数据绑定

  • 支持样式和模板

  • 支持动画

  • 支持 MVVM 架构

  • UI 表现力比 WinForms 更强


2. WPF 和 WinForms 有什么区别?

答:

WinForms 是传统控件式开发,简单直接,适合快速做管理系统。

WPF 使用 XAML 描述 UI,支持数据绑定、样式、模板、动画,更适合复杂界面。

主要区别:

  • WinForms 更简单,上手快

  • WPF UI 更灵活,界面表现更强

  • WPF 更适合 MVVM

  • WPF 支持强大的数据绑定

  • WPF 控件可以通过模板完全自定义外观


3. XAML 是什么?

答:

XAML 是一种声明式 XML 语言,用来描述 WPF 的界面。

例如:

复制代码
<Button Content="保存" Width="100" Height="30" />

它的作用是把界面结构和后台逻辑分离。

通常:

  • XAML 写界面

  • C# 写业务逻辑


4. WPF 中什么是数据绑定?

答:

数据绑定是 UI 控件和数据对象之间的自动同步机制。

例如:

复制代码
<TextBox Text="{Binding UserName}" />

如果 UserName 变化,界面可以自动更新。

常见绑定模式:

  • OneWay:数据源到界面

  • TwoWay:界面和数据源双向同步

  • OneTime:只绑定一次

  • OneWayToSource:界面到数据源


5. WPF 中 DataContext 是什么?

答:

DataContext 是绑定的数据上下文。

比如:

复制代码
this.DataContext = new MainViewModel();

XAML 中的绑定:

复制代码
<TextBox Text="{Binding UserName}" />

会从当前控件的 DataContext 中查找 UserName 属性。

DataContext 会沿着控件树向下继承,子控件默认可以使用父控件的 DataContext


6. 什么是 MVVM?

答:

MVVM 是 WPF 常用架构模式。

  • Model:数据模型

  • View:界面

  • ViewModel:界面数据和业务逻辑

优点:

  • 界面和逻辑分离

  • 方便维护

  • 方便单元测试

  • 减少后台代码

  • 更适合复杂桌面项目


7. INotifyPropertyChanged 有什么作用?

答:

INotifyPropertyChanged 用来通知界面属性发生变化。

如果 ViewModel 中属性变化后要让 UI 自动刷新,就需要实现它。

复制代码
public class MainViewModel : INotifyPropertyChanged
{
    private string _userName;

    public string UserName
    {
        get => _userName;
        set
        {
            _userName = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UserName)));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

8. WPF 中 Command 是什么?

答:

Command 用来把按钮点击等操作绑定到 ViewModel,代替传统事件。

复制代码
<Button Content="保存" Command="{Binding SaveCommand}" />

优点:

  • 符合 MVVM

  • 减少后台事件代码

  • 方便测试

  • 可以通过 CanExecute 控制按钮是否可用


9. ICommand 包含哪些成员?

答:

ICommand 包含:

复制代码
bool CanExecute(object parameter);
void Execute(object parameter);
event EventHandler CanExecuteChanged;

含义:

  • Execute:真正执行的逻辑

  • CanExecute:判断命令是否可以执行

  • CanExecuteChanged:通知界面重新判断按钮是否可用


10. 什么是依赖属性?

答:

依赖属性是 WPF 特有的属性系统。

它支持:

  • 数据绑定

  • 样式

  • 动画

  • 默认值

  • 属性变化通知

  • 属性值继承

常用于自定义控件。

示例:

复制代码
public static readonly DependencyProperty TitleProperty =
    DependencyProperty.Register(
        "Title",
        typeof(string),
        typeof(MyControl),
        new PropertyMetadata("")
    );

public string Title
{
    get => (string)GetValue(TitleProperty);
    set => SetValue(TitleProperty, value);
}

11. 普通属性和依赖属性有什么区别?

答:

普通属性只是 C# 属性。

依赖属性由 WPF 属性系统管理。

区别:

  • 依赖属性支持 Binding

  • 依赖属性支持 Style

  • 依赖属性支持 Animation

  • 依赖属性支持默认值和变化回调

  • 普通属性更简单,适合普通业务对象

ViewModel 一般用普通属性 + INotifyPropertyChanged

自定义控件一般用依赖属性。


12. WPF 中资源 Resource 是什么?

答:

Resource 是 WPF 中可复用的对象,比如颜色、样式、模板、数据源等。

复制代码
<Window.Resources>
    <SolidColorBrush x:Key="MainBrush" Color="Blue" />
</Window.Resources>

使用:

复制代码
<Button Background="{StaticResource MainBrush}" />

资源可以定义在:

  • 控件级别

  • Window 级别

  • Application 级别

  • ResourceDictionary 文件中


13. StaticResourceDynamicResource 有什么区别?

答:

StaticResource 在加载时查找资源,性能更好,适合不变化的资源。

复制代码
Background="{StaticResource MainBrush}"

DynamicResource 在运行时动态查找资源,资源变化时界面可以更新。

复制代码
Background="{DynamicResource MainBrush}"

比如运行时切换主题时,可以使用 DynamicResource


14. Style 和 Template 有什么区别?

答:

Style 用来设置控件属性,比如颜色、字体、边距。

复制代码
<Style TargetType="Button">
    <Setter Property="Foreground" Value="White" />
</Style>

Template 用来定义控件的结构和外观。

复制代码
<ControlTemplate TargetType="Button">
    <Border Background="Blue">
        <ContentPresenter />
    </Border>
</ControlTemplate>

简单说:

  • Style 改属性

  • Template 改控件长什么样


15. ControlTemplateDataTemplate 有什么区别?

答:

ControlTemplate 定义控件本身的外观结构。

比如改变 Button 的外观。

DataTemplate 定义数据对象显示成什么样。

比如 ListBox 中每一项怎么显示。

复制代码
<DataTemplate>
    <StackPanel>
        <TextBlock Text="{Binding Name}" />
        <TextBlock Text="{Binding Age}" />
    </StackPanel>
</DataTemplate>

16. WPF 布局容器有哪些?

答:

常见布局容器:

  • Grid:表格布局,最常用

  • StackPanel:横向或纵向排列

  • DockPanel:停靠布局

  • WrapPanel:自动换行排列

  • Canvas:绝对定位

面试可以说:

实际开发中我最常用 Grid 和 StackPanel,复杂界面用 Grid,简单排列用 StackPanel。


17. WPF 中如何避免界面卡死?

答:

不要在 UI 线程执行耗时操作。

比如:

  • 数据库查询

  • 网络请求

  • 大文件读写

  • 大量数据计算

应该使用异步:

复制代码
private async void Button_Click(object sender, RoutedEventArgs e)
{
    var data = await Task.Run(() => LoadData());
    MyList.ItemsSource = data;
}

如果后台线程要更新 UI,需要切回 UI 线程:

复制代码
Dispatcher.Invoke(() =>
{
    TextBlock.Text = "加载完成";
});

18. WPF 中 Dispatcher 是什么?

答:

Dispatcher 是 WPF UI 线程的消息调度器。

WPF 控件只能在创建它的 UI 线程访问。

后台线程如果要更新 UI,需要使用:

复制代码
Dispatcher.Invoke(() =>
{
    label.Content = "完成";
});

或:

复制代码
await Dispatcher.InvokeAsync(() =>
{
    label.Content = "完成";
});

19. ObservableCollection<T> 有什么作用?

答:

ObservableCollection<T> 是支持集合变化通知的集合。

当添加、删除元素时,绑定的 UI 可以自动刷新。

复制代码
public ObservableCollection<User> Users { get; set; }

常用于:

  • ListBox

  • DataGrid

  • ComboBox

注意:

ObservableCollection<T> 通知的是集合增删变化,不是集合中某个对象属性变化。对象属性变化仍然需要实现 INotifyPropertyChanged


20. WPF 中 DataGrid 数据很多时怎么优化?

答:

优化方式:

  • 分页加载数据

  • 开启行虚拟化

  • 开启列虚拟化

  • 减少复杂模板

  • 避免一次性加载全部数据

  • 数据库查询加索引

  • 后台异步加载

示例:

复制代码
<DataGrid EnableRowVirtualization="True"
          EnableColumnVirtualization="True"
          VirtualizingPanel.IsVirtualizing="True" />

21. WPF 事件和 Command 怎么选择?

答:

简单界面或和 UI 强相关的逻辑,可以用事件。

比如窗口加载、鼠标移动、控件动画。

业务操作更推荐 Command。

比如:

  • 保存

  • 删除

  • 查询

  • 登录

  • 提交

面试可以说:

如果使用 MVVM,我会优先用 Command 处理业务操作,减少 View 后台代码。


22. WPF 中 Binding 失败怎么排查?

答:

常见排查方向:

  • DataContext 是否设置正确

  • 属性名是否写错

  • 属性是否是 public

  • 是否实现 INotifyPropertyChanged

  • 绑定路径是否正确

  • 输出窗口是否有 Binding 错误

  • 集合是否使用 ObservableCollection<T>


23. UserControlCustomControl 有什么区别?

答:

UserControl 是把多个已有控件组合成一个控件,开发简单。

CustomControl 是自定义控件,通常配合 ControlTemplate,可定制性更强。

区别:

  • UserControl 适合业务控件组合

  • CustomControl 适合通用控件库

  • CustomControl 更适合支持样式和模板

  • UserControl 开发更快


24. WPF 中路由事件是什么?

答:

路由事件不是只在当前控件处理,而是可以沿控件树传播。

常见有三种:

  • 冒泡事件:从子控件向父控件传播

  • 隧道事件:从父控件向子控件传播,通常以 Preview 开头

  • 直接事件:只在当前控件触发

比如 Button 点击事件可以向上冒泡到父容器。


25. WPF 中常见的性能问题有哪些?

答:

常见问题:

  • UI 线程执行耗时任务

  • 一次性加载大量数据

  • DataGrid 未开启虚拟化

  • 绑定过多或绑定路径复杂

  • 控件层级太深

  • 复杂动画过多

  • 图片资源过大

  • 频繁刷新 UI

优化思路:

  • 异步加载

  • 分页

  • 虚拟化

  • 简化模板

  • 减少不必要绑定

  • 图片压缩

  • 用日志或性能工具定位瓶颈


26. WPF 面试项目怎么说?

答:

可以这样回答:

我做过 WPF 桌面管理系统,界面使用 XAML 编写,采用 MVVM 思路,把界面展示和业务逻辑分开。

ViewModel 中通过 INotifyPropertyChanged 通知界面刷新,列表数据使用 ObservableCollection<T>,按钮操作使用 ICommand

项目中遇到过界面卡顿问题,我把数据库查询和文件处理放到后台线程,用 async/await 优化,同时对 DataGrid 做分页和虚拟化,提高了界面响应速度。

对异常问题,我会记录日志,包括异常信息、堆栈、操作用户和关键参数,方便后续排查。


你可以优先背这几个高频点:

XAMLDataContextBindingINotifyPropertyChangedObservableCollectionICommandMVVMDependencyPropertyDispatcherDataTemplateControlTemplateStaticResource/DynamicResourceDataGrid 虚拟化

相关推荐
程序猿编码1 小时前
如何把远程文件变化“骗“成本地inotify事件:一个LD_PRELOAD钩子
c语言·开发语言·网络·tcp/ip·安全
星空椰10 小时前
Python 面向对象高级:继承与类定义详解
开发语言·python
白露与泡影10 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
凯瑟琳.奥古斯特10 小时前
高阶子查询题目精炼
开发语言·数据库·python·职场和发展·数据库开发
雪度娃娃10 小时前
转向现代C++——在意为改写的函数添加 override
开发语言·c++
喵星人工作室11 小时前
C++火影忍者1.1.2
开发语言·c++
basketball61612 小时前
C++ 中的 ptrdiff_t 详解
开发语言·c++
月亮邮递员61612 小时前
Markdown语法总结
开发语言·前端·javascript
printfLILEI12 小时前
php中的类与对象以及反序列化
linux·开发语言·php