使用多个Radiobutton来切换不同的UserControl来实现。
Radiobutton的样式已在上篇文章中给出。
Service代码
/// <summary>
/// 页面导航注册服务类
/// </summary>
public class SimpleNavigationService
{
#region 懒加载实现单例
private static readonly Lazy<SimpleNavigationService> _instance = new Lazy<SimpleNavigationService>(() => new SimpleNavigationService());
public static SimpleNavigationService Instance => _instance.Value;
private SimpleNavigationService()
{
}
#endregion 懒加载实现单例
private readonly Dictionary<PageEnum, UserControl> _instances = new Dictionary<PageEnum, UserControl>();
/// <summary>
/// 注册界面
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
public void Register<T>(PageEnum key) where T : UserControl, new()
{
_instances[key] = new T();
}
public UserControl Navigate(PageEnum key)
{
if (_instances.TryGetValue(key, out UserControl instance))
{
return instance;
}
throw new ArgumentException($"页面未注册: {key}");
}
}
其中只有注册页面和切换页面。
ViewModel如下:
public class NavigationViewModel : ViewModelBase
{
public NavigationViewModel()
{
NavigateCommand = new Command<PageEnum>(Navigate);
// 注册页面
SimpleNavigationService? simpleNavigationService = SimpleNavigationService.Instance;
simpleNavigationService.Register<MainUserControl>(PageEnum.MainPage);
simpleNavigationService.Register<ImgCalUserControl>(PageEnum.ImgCalPage);
simpleNavigationService.Register<FeatureMatchUserControl>(PageEnum.FeatureMatchPage);
simpleNavigationService.Register<FeatureDetectUserControl>(PageEnum.FeatureDetectPage);
simpleNavigationService.Register<MorphologicalOperationsControl>(PageEnum.MorphologicalPage);
simpleNavigationService.Register<TextUserControl>(PageEnum.TextPage);
simpleNavigationService.Register<FloodFillUserControl>(PageEnum.FloodFillPage);
simpleNavigationService.Register<MosaicUserControl>(PageEnum.MosaicPage);
simpleNavigationService.Register<FaceRecognitionUserControl>(PageEnum.FaceRecognitionPage);
//设置默认界面
CurrentPage = SimpleNavigationService.Instance.Navigate(PageEnum.MainPage);
}
private object _currentPage;
/// <summary>
/// 当前页面
/// </summary>
public object CurrentPage
{
get => _currentPage;
set
{
_currentPage = value;
OnPropertyChanged();
}
}
/// <summary>
/// 切换界面 命令
/// </summary>
public ICommand NavigateCommand
{
get;
}
/// <summary>
/// 切换界面
/// </summary>
/// <param name="dstPage"></param>
private void Navigate(PageEnum dstPage)
{
// 用属性赋值
CurrentPage = SimpleNavigationService.Instance.Navigate(dstPage);
}
}
注册界面的方法可以放到程序入口。
页面的枚举:
public enum PageEnum
{
[Description("主界面")]
MainPage = 0,
[Description("算数运算")]
ImgCalPage,
[Description("特征匹配")]
FeatureMatchPage,
[Description("特征检测")]
FeatureDetectPage,
[Description("形态学操作")]
MorphologicalPage,
[Description("文本操作")]
TextPage,
[Description("水漫操作")]
FloodFillPage,
[Description("马赛克")]
MosaicPage,
[Description("人脸识别")]
FaceRecognitionPage,
}
记得添加Description,可以直接在界面xaml上直接绑定显示,直接采用ItemsControl进行绑定枚举所有的成员,而不用定义多个RadioButton。 xaml文件绑定:
<ItemsControl ItemsSource="{Binding Source={StaticResource PageEnumValues}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
Style="{StaticResource MenuBtnStyle}"
Content="{Binding Path=., Converter={StaticResource enumDesConverter}}"
IsChecked="{Binding Path=., Converter={StaticResource enumFirstToBoolConverter}}"
CommandParameter="{Binding Path=.}"
Command="{Binding DataContext.NavigationViewModel.NavigateCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
GroupName="PageEnumGroup" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
其中需要在主xaml上定义资源
<ObjectDataProvider x:Key="PageEnumValues" MethodName="GetValues" ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="models:PageEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
转换器 枚举->枚举描述
internal class EnumToDescriptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is Enum enumValue)
{
return enumValue.GetDescription();
}
return value?.ToString() ?? string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
转换器 枚举-> 布尔值
internal class EnumFirstToBoolConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value.GetType().IsEnum == true)
{
Type enumType = value.GetType();
var firstValue = Enum.GetValues(enumType).Cast<object>().First();
return value.Equals(firstValue);
}
return false;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
根据其枚举值是否是第一个 来设置Radiobutton初始是不是选中状态,用来设置默认界面。
界面上用来显示不同的界面即不同用户控件。
<ContentPresenter Grid.Column="1" Content="{Binding NavigationViewModel.CurrentPage}" />
添加新的界面的时候只需要 在PageEnum中添加项 和 在SimpleNavigationService中注册对应界面即可。不需要在修改xaml中的东西。