AgentSkillsCN

wpf-mvvm

本项目WPF MVVM模式指南。在添加新视图、视图模型、命令、数据绑定、转换器,或UI组件时使用此功能。可通过“创建新的UserControl或Window”、“添加数据绑定”、“实现ICommand”、“创建值转换器”或“使用ResourceDictionary/样式”等短语触发。

SKILL.md
--- frontmatter
name: wpf-mvvm
description: "WPF MVVM pattern guide for this project. Use when adding new views, view models, commands, data bindings, converters, or UI components. Triggers on: creating new UserControls or Windows, adding data bindings, implementing ICommand, creating value converters, or working with ResourceDictionary/styles."

WPF MVVM Patterns

Architecture

This project uses MVVM without a framework. Key base classes:

  • ViewModelBase (ViewModels/ViewModelBase.cs): INotifyPropertyChanged with SetProperty<T> helper
  • RelayCommand (ViewModels/RelayCommand.cs): ICommand implementation with Action/Func constructors

Adding a New View + ViewModel

  1. Create ViewModel in ViewModels/:
csharp
namespace WinContextMenuEditor.ViewModels;

public class FooViewModel : ViewModelBase
{
    private string _bar = string.Empty;
    public string Bar
    {
        get => _bar;
        set => SetProperty(ref _bar, value);
    }

    public ICommand DoSomethingCommand { get; }

    public FooViewModel()
    {
        DoSomethingCommand = new RelayCommand(OnDoSomething);
    }

    private void OnDoSomething() { /* ... */ }
}
  1. Create View XAML in Views/:
xml
<UserControl x:Class="WinContextMenuEditor.Views.FooView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:vm="clr-namespace:WinContextMenuEditor.ViewModels">
    <UserControl.DataContext>
        <vm:FooViewModel/>
    </UserControl.DataContext>
    <!-- Use {Binding PropertyName} for data binding -->
</UserControl>

App-Level Resources

Registered in App.xaml:

  • {StaticResource BoolToVis} - BoolToVisibilityConverter (supports ConverterParameter=Invert)
  • {StaticResource InvertBoolConverter} - inverts bool values
  • Styles: ActionButton, ToolbarButton, FormLabel, FormTextBox, SearchTextBox, CategoryListBox, StatusBar
  • Strings: {DynamicResource KeyName} for i18n (see Resources/Strings.*.xaml)

i18n

  • Add entries to both Resources/Strings.en-US.xaml and Resources/Strings.ja-JP.xaml
  • Use {DynamicResource StringKey} in XAML (not StaticResource - dynamic enables runtime switching)

Dialog Pattern

For modal dialogs (see AddEditDialog as example):

  1. Create Window with DataContext bound to dialog ViewModel
  2. Set DialogResult in code-behind OK/Cancel click handlers
  3. Show with dialog.ShowDialog() == true

Conventions

  • Properties: use SetProperty(ref _field, value) for change notification
  • Commands: RelayCommand with Action or Action<object?> + optional Func<bool> canExecute
  • Converters: register in App.xaml ResourceDictionary
  • Keep code-behind minimal - logic in ViewModels, UI wiring only in code-behind