xceed PropertyGrid 如何做成Visual Studio 的属性窗口样子
类似这样的,我百度了一下,发现使用Xceed 不错。使用PropertyGrid
前台代码为
<Window
x:Class="WpfApp.MainWindow"
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:WpfApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Title="PropertyGrid Event Example"
Width="800"
Height="450"
d:DataContext="{d:DesignInstance Type=local:MainViewModel}"
mc:Ignorable="d">
<Window.Resources>
<!-- 定义转换器 -->
<local:CommandItemToCommandConverter x:Key="CommandItemToCommandConverter" />
<!-- 定义模板 -->
<DataTemplate x:Key="EventEditTemplate">
<StackPanel Orientation="Horizontal">
<!-- 下拉框选择命令 -->
<ComboBox
Width="150"
DisplayMemberPath="Name"
ItemsSource="{Binding DataContext.ButtonViewModel.Commands, RelativeSource={RelativeSource AncestorType=Window}}"
SelectedItem="{Binding DataContext.ButtonViewModel.EventClick, RelativeSource={RelativeSource AncestorType=Window}, Converter={StaticResource CommandItemToCommandConverter}, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<StackPanel Orientation="Vertical">
<!-- PropertyGrid that binds to the Button object -->
<xctk:PropertyGrid Name="MyPropertyGrid" SelectedObject="{Binding ButtonViewModel}">
<xctk:PropertyGrid.EditorDefinitions>
<xctk:EditorTemplateDefinition EditingTemplate="{StaticResource EventEditTemplate}" TargetProperties="EventClick" />
</xctk:PropertyGrid.EditorDefinitions>
</xctk:PropertyGrid>
<Button
Width="100"
Height="100"
Command="{Binding ButtonViewModel.EventClick, NotifyOnSourceUpdated=True}"
Content="sub" />
</StackPanel>
</Window>
后台代码为
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xaml;
using static WpfApp.ButtonViewModel;
namespace WpfApp
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel(); // Set the DataContext to ViewModel
}
}
public class MainViewModel
{
public ButtonViewModel ButtonViewModel { get; }
public MainViewModel()
{
ButtonViewModel = new ButtonViewModel();
}
}
public class CommandItemToCommandConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{// 将 ICommand 转换回 CommandItem
if (value is ICommand command)
{
var viewModel = Application.Current.MainWindow.DataContext as ButtonViewModel;
if (viewModel != null)
{
return viewModel.Commands.FirstOrDefault(item => item.Command == command);
}
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// 从 CommandItem 提取 ICommand
if (value is CommandItem commandItem)
{
return commandItem.Command;
}
return null;
}
}
public class CommandItem
{
public string Name { get; set; }
public ICommand Command { get; set; }
}
public class ButtonViewModel : INotifyPropertyChanged
{
private ICommand _eventClick;
public ObservableCollection<CommandItem> Commands { get; set; }
public ICommand EventClick
{
get => _eventClick;
set
{
_eventClick = value;
OnPropertyChanged(nameof(EventClick));
}
}
public ButtonViewModel()
{
Commands = new ObservableCollection<CommandItem>
{
new CommandItem
{
Name = "Say Hello",
Command = new RelayCommand(_ => MessageBox.Show("Hello!"))
},
new CommandItem
{
Name = "Say Goodbye",
Command = new RelayCommand(_ => MessageBox.Show("Goodbye!"))
}
};
// 初始化默认命令
EventClick = Commands.FirstOrDefault()?.Command;
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute) : this(execute, null)
{ }
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
}
这是一个完整可以运行的例子。其实要做成vs 那样的,路途很遥远,这里只是举个例子,需要重写很多模板,像前面的代码中就是定义了Event 选择的模板
实际运行效果如下:
原文地址:https://blog.csdn.net/u013409510/article/details/145308126
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!