目录
一 上章回顾
一 上章回顾
二 实现ICommand 接口
三 字段
四 构造函数
五 属性
六 订阅可执行状态改变
七 刷新
八 总结
九 下章预告
二 继承视图模型基类
public class MainWindowViewModel : ViewModelBase
三 构造函数
通过依赖注入的方式传入SnackbarMessageQueue对象和首页
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, string? startupPage)
{
//生成主页并加入集合,初始化 DemoItems 集合,并添加 "Home" 项
DemoItems = new ObservableCollection<DemoItem>
{
new DemoItem(
"Home",
typeof(Home),
new[]
{
new DocumentationLink(
DocumentationLinkType.Wiki,
$"{ConfigurationManager.AppSettings["GitHub"]}/wiki",
"WIKI"),
DocumentationLink.DemoPageLink<Home>()
},
selectedIcon: PackIconKind.Home,
unselectedIcon: PackIconKind.HomeOutline)
};
//遍历生成的菜单集合,按照菜单名排序并加入示例菜单
foreach (var item in GenerateDemoItems(snackbarMessageQueue).OrderBy(i => i.Name))
{
DemoItems.Add(item);
}
//筛选菜单名符合要求的菜单加入主要示例菜单
MainDemoItems = new ObservableCollection<DemoItem>
{
DemoItems.First(x => x.Name == "Home"),
DemoItems.First(x => x.Name == "Buttons"),
DemoItems.First(x => x.Name == "Toggles"),
DemoItems.First(x => x.Name == "Fields"),
DemoItems.First(x => x.Name == "Pickers")
};
//根据 startupPage 参数的值来选择一个初始的 DemoItem,如果找不到匹配的项,则选择 DemoItems 集合中的第一个项。
SelectedItem = DemoItems.FirstOrDefault(di => string.Equals(di.Name, startupPage, StringComparison.CurrentCultureIgnoreCase)) ?? DemoItems.First();
//根据关键字过滤菜单
_demoItemsView = CollectionViewSource.GetDefaultView(DemoItems);
_demoItemsView.Filter = DemoItemsFilter;
四 初始化命令
//主页命令
HomeCommand = new AnotherCommandImplementation(
_ =>
{
SearchKeyword = string.Empty;
SelectedIndex = 0;
});前页导航
MovePrevCommand = new AnotherCommandImplementation(
_ =>
{
if (!string.IsNullOrWhiteSpace(SearchKeyword))
SearchKeyword = string.Empty;SelectedIndex--;
},
_ => SelectedIndex > 0);后页导航
MoveNextCommand = new AnotherCommandImplementation(
_ =>
{
if (!string.IsNullOrWhiteSpace(SearchKeyword))
SearchKeyword = string.Empty;SelectedIndex++;
},
_ => SelectedIndex < DemoItems.Count - 1);忽视所有通知命令
DismissAllNotificationsCommand = new AnotherCommandImplementation(
_ => DemoItems[0].DismissAllNotifications(),
_ => DemoItems[0].Notifications != null);新增通知命令
AddNewNotificationCommand = new AnotherCommandImplementation(
_ => DemoItems[0].AddNewNotification());AddNewNotificationCommand.Execute(new object());
}
五 字段
视图集合
private readonly ICollectionView _demoItemsView;
类型为示范项目的选中项
private DemoItem? _selectedItem;选中项索引
private int _selectedIndex;搜索关键词
private string? _searchKeyword;控件启用状态
private bool _controlsEnabled = true;
六 属性
搜索关键词,如果属性更新,刷新示范项目视图
public string? SearchKeyword
{
get => _searchKeyword;
set
{
if (SetProperty(ref _searchKeyword, value))
{
_demoItemsView.Refresh();
}
}
}示范项目动态数据集合
public ObservableCollection<DemoItem> DemoItems { get; }
主要示范项目动态数据集合
public ObservableCollection<DemoItem> MainDemoItems { get; }选中项
public DemoItem? SelectedItem
{
get => _selectedItem;
set => SetProperty(ref _selectedItem, value);
}选中索引
public int SelectedIndex
{
get => _selectedIndex;
set => SetProperty(ref _selectedIndex, value);
}控件启用状态
public bool ControlsEnabled
{
get => _controlsEnabled;
set => SetProperty(ref _controlsEnabled, value);
}
七 命令
主页命令
public AnotherCommandImplementation HomeCommand { get; }
前页导航命令
public AnotherCommandImplementation MovePrevCommand { get; }后页导航命令
public AnotherCommandImplementation MoveNextCommand { get; }忽略所有通知命令
public AnotherCommandImplementation DismissAllNotificationsCommand { get; }新增通知命令
public AnotherCommandImplementation AddNewNotificationCommand { get; }
八 方法
/// <summary>
/// 根据通知条消息队列生成导航菜单动态集合
/// </summary>
/// <param name="snackbarMessageQueue"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
private static IEnumerable<DemoItem> GenerateDemoItems(ISnackbarMessageQueue snackbarMessageQueue)
{
//通知条消息队列为空
if (snackbarMessageQueue is null)
throw new ArgumentNullException(nameof(snackbarMessageQueue));
//调色板
yield return new DemoItem(
"Palette",
typeof(PaletteSelector),
new[]
{
DocumentationLink.WikiLink("Brush-Names", "Brushes"),
DocumentationLink.WikiLink("Custom-Palette-Hues", "Custom Palettes"),
DocumentationLink.WikiLink("Swatches-and-Recommended-Colors", "Swatches"),
DocumentationLink.DemoPageLink<PaletteSelector>("Demo View"),
DocumentationLink.DemoPageLink<PaletteSelectorViewModel>("Demo View Model"),
DocumentationLink.ApiLink<PaletteHelper>()
},
selectedIcon: PackIconKind.Palette,
unselectedIcon: PackIconKind.PaletteOutline);
//颜色工具
yield return new DemoItem(
"Color Tool",
typeof(ColorTool),
new[]
{
DocumentationLink.WikiLink("Brush-Names", "Brushes"),
DocumentationLink.WikiLink("Custom-Palette-Hues", "Custom Palettes"),
DocumentationLink.WikiLink("Swatches-and-Recommended-Colors", "Swatches"),
DocumentationLink.DemoPageLink<ColorTool>("Demo View"),
DocumentationLink.DemoPageLink<ColorToolViewModel>("Demo View Model"),
DocumentationLink.ApiLink<PaletteHelper>()
},
selectedIcon: PackIconKind.Eyedropper,
unselectedIcon: PackIconKind.EyedropperVariant);
//按钮
yield return new DemoItem(
"Buttons",
typeof(Buttons),
new[]
{
DocumentationLink.WikiLink("Button-Styles", "Buttons"),
DocumentationLink.DemoPageLink<Buttons>("Demo View"),
DocumentationLink.DemoPageLink<ButtonsViewModel>("Demo View Model"),
DocumentationLink.StyleLink("Button"),
DocumentationLink.StyleLink("PopupBox"),
DocumentationLink.ApiLink<PopupBox>()
},
selectedIcon: PackIconKind.GestureTapHold,
unselectedIcon: PackIconKind.GestureTapHold);
//触发器
yield return new DemoItem(
"Toggles",
typeof(Toggles),
new[]
{
DocumentationLink.DemoPageLink<Toggles>(),
DocumentationLink.StyleLink("ToggleButton", true),
DocumentationLink.StyleLink("CheckBox")
},
selectedIcon: PackIconKind.ToggleSwitch,
unselectedIcon: PackIconKind.ToggleSwitchOffOutline);
//评分控件
yield return new DemoItem(
"Rating Bar",
typeof(RatingBar),
new[]
{
DocumentationLink.DemoPageLink<RatingBar>(),
DocumentationLink.StyleLink("RatingBar"),
DocumentationLink.ApiLink<RatingBar>()
},
selectedIcon: PackIconKind.Star,
unselectedIcon: PackIconKind.StarOutline);
//懒加载字段
yield return new DemoItem(
"Fields",
typeof(Fields),
new[]
{
DocumentationLink.DemoPageLink<Fields>(),
DocumentationLink.StyleLink("TextBox")
},
selectedIcon: PackIconKind.Pencil,
unselectedIcon: PackIconKind.PencilOutline);
//懒加载表单对齐
yield return new DemoItem(
"Fields line up",
typeof(FieldsLineUp),
new[]
{
DocumentationLink.DemoPageLink<FieldsLineUp>()
},
selectedIcon: PackIconKind.PencilBox,
unselectedIcon: PackIconKind.PencilBoxOutline);
//懒加载下拉组合框
yield return new DemoItem(
"ComboBoxes",
typeof(ComboBoxes),
new[]
{
DocumentationLink.DemoPageLink<ComboBoxes>(),
DocumentationLink.StyleLink("ComboBox")
},
selectedIcon: PackIconKind.CheckboxMarked,
unselectedIcon: PackIconKind.CheckboxMarkedOutline);
//懒加载选择器
yield return new DemoItem(
"Pickers",
typeof(Pickers),
new[]
{
DocumentationLink.DemoPageLink<Pickers>(),
DocumentationLink.StyleLink("Clock"),
DocumentationLink.StyleLink("DatePicker"),
DocumentationLink.ApiLink<TimePicker>()
},
selectedIcon: PackIconKind.Clock,
unselectedIcon: PackIconKind.ClockOutline);
//懒加载滑动条
yield return new DemoItem(
"Sliders",
typeof(Sliders),
new[]
{
DocumentationLink.DemoPageLink<Sliders>(),
DocumentationLink.StyleLink("Slider")
},
selectedIcon: PackIconKind.TuneVariant,
unselectedIcon: PackIconKind.TuneVariant);
//懒加载标签
yield return new DemoItem(
"Chips",
typeof(Chips),
new[]
{
DocumentationLink.DemoPageLink<Chips>(),
DocumentationLink.StyleLink("Chip"),
DocumentationLink.ApiLink<Chip>()
},
selectedIcon: PackIconKind.None,
unselectedIcon: PackIconKind.None);
//懒加载排版设计
yield return new DemoItem(
"Typography",
typeof(Typography),
new[]
{
DocumentationLink.DemoPageLink<Typography>(),
DocumentationLink.StyleLink("TextBlock", true)
},
selectedIcon: PackIconKind.FormatSize,
unselectedIcon: PackIconKind.FormatTitle)
{
HorizontalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto
};
//懒加载卡片
yield return new DemoItem(
"Cards",
typeof(Cards),
new[]
{
DocumentationLink.DemoPageLink<Cards>(),
DocumentationLink.StyleLink("Card"),
DocumentationLink.ApiLink<Card>()
},
selectedIcon: PackIconKind.Card,
unselectedIcon: PackIconKind.CardOutline);
//懒加载图标包
yield return new DemoItem(
"Icon Pack",
typeof(IconPack),
new[]
{
DocumentationLink.DemoPageLink<IconPack>("Demo View"),
DocumentationLink.DemoPageLink<IconPackViewModel>("Demo View Model"),
DocumentationLink.ApiLink<PackIcon>()
},
selectedIcon: PackIconKind.Robot,
unselectedIcon: PackIconKind.RobotOutline,
new IconPackViewModel(snackbarMessageQueue))
{
VerticalScrollBarVisibilityRequirement = ScrollBarVisibility.Disabled
};
//懒加载有色区域
yield return new DemoItem(
"Colour Zones",
typeof(ColorZones),
new[]
{
DocumentationLink.DemoPageLink<ColorZones>(),
DocumentationLink.ApiLink<ColorZone>()
},
selectedIcon: PackIconKind.Subtitles,
unselectedIcon: PackIconKind.SubtitlesOutline);
//懒加载列表控件
yield return new DemoItem(
"Lists",
typeof(Lists),
new[]
{
DocumentationLink.DemoPageLink<Lists>("Demo View"),
DocumentationLink.DemoPageLink<ListsAndGridsViewModel>("Demo View Model", "Domain"),
DocumentationLink.StyleLink("ListBox"),
DocumentationLink.StyleLink("ListView")
},
selectedIcon: PackIconKind.FormatListBulletedSquare,
unselectedIcon: PackIconKind.FormatListCheckbox);
//懒加载树形控件
yield return new DemoItem(
"Trees",
typeof(Trees),
new[]
{
DocumentationLink.DemoPageLink<Trees>("Demo View"),
DocumentationLink.DemoPageLink<TreesViewModel>("Demo View Model"),
DocumentationLink.StyleLink("TreeView")
},
selectedIcon: PackIconKind.FileTree,
unselectedIcon: PackIconKind.FileTreeOutline);
//懒加载数据网格
yield return new DemoItem(
"Data Grids",
typeof(DataGrids),
new[]
{
DocumentationLink.DemoPageLink<DataGrids>("Demo View"),
DocumentationLink.DemoPageLink<ListsAndGridsViewModel>("Demo View Model", "Domain"),
DocumentationLink.StyleLink("DataGrid")
},
selectedIcon: PackIconKind.ViewGrid,
unselectedIcon: PackIconKind.ViewGridOutline);
//懒加载折叠面板
yield return new DemoItem(
"Expander",
typeof(Expander),
new[]
{
DocumentationLink.DemoPageLink<Expander>(),
DocumentationLink.StyleLink("Expander")
},
selectedIcon: PackIconKind.UnfoldMoreHorizontal,
unselectedIcon: PackIconKind.UnfoldMoreHorizontal);
//懒加载组件框
yield return new DemoItem(
"Group Boxes",
typeof(GroupBoxes),
new[]
{
DocumentationLink.DemoPageLink<GroupBoxes>(),
DocumentationLink.StyleLink("GroupBox")
},
selectedIcon: PackIconKind.TextBoxMultiple,
unselectedIcon: PackIconKind.TextBoxMultipleOutline);
//懒加载菜单工具栏
yield return new DemoItem(
"Menus & Tool Bars",
typeof(MenusAndToolBars),
new[]
{
DocumentationLink.DemoPageLink<MenusAndToolBars>(),
DocumentationLink.StyleLink("Menu"),
DocumentationLink.StyleLink("ToolBar")
},
selectedIcon: PackIconKind.DotsHorizontalCircle,
unselectedIcon: PackIconKind.DotsHorizontalCircleOutline);
//懒加载进度条
yield return new DemoItem(
"Progress Indicators",
typeof(Progress),
new[]
{
DocumentationLink.DemoPageLink<Progress>(),
DocumentationLink.StyleLink("ProgressBar")
},
selectedIcon: PackIconKind.ProgressClock,
unselectedIcon: PackIconKind.ProgressClock);
//懒加载垂直导航栏
yield return new DemoItem(
"Navigation Rail",
typeof(NavigationRail),
new[]
{
DocumentationLink.DemoPageLink<NavigationRail>(),
DocumentationLink.StyleLink("NavigationRail", true),
},
selectedIcon: PackIconKind.NavigationVariant,
unselectedIcon: PackIconKind.NavigationVariantOutline)
{
HorizontalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto
};
//懒加载水平导航栏
yield return new DemoItem(
"Navigation Bar",
typeof(NavigationBar),
new[]
{
DocumentationLink.DemoPageLink<NavigationBar>(),
DocumentationLink.StyleLink("NavigationBar", true),
},
selectedIcon: PackIconKind.NavigationVariant,
unselectedIcon: PackIconKind.NavigationVariantOutline)
{
HorizontalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto
};
//懒加载对话框
yield return new DemoItem(
"Dialogs",
typeof(Dialogs),
new[]
{
DocumentationLink.WikiLink("Dialogs", "Dialogs"),
DocumentationLink.DemoPageLink<Dialogs>("Demo View"),
DocumentationLink.DemoPageLink<DialogsViewModel>("Demo View Model", "Domain"),
DocumentationLink.ApiLink<DialogHost>()
},
selectedIcon: PackIconKind.CommentAlert,
unselectedIcon: PackIconKind.CommentAlertOutline)
{
HorizontalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto
};
//懒加载抽屉
yield return new DemoItem(
"Drawer",
typeof(Drawers),
new[]
{
DocumentationLink.DemoPageLink<Drawers>("Demo View"),
DocumentationLink.ApiLink<DrawerHost>()
},
selectedIcon: PackIconKind.ExpandAll,
unselectedIcon: PackIconKind.ExpandAll);
//懒加载通知条
yield return new DemoItem(
"Snackbar",
typeof(Snackbars),
new[]
{
DocumentationLink.WikiLink("Snackbar", "Snackbar"),
DocumentationLink.DemoPageLink<Snackbars>(),
DocumentationLink.StyleLink("Snackbar"),
DocumentationLink.ApiLink<Snackbar>(),
DocumentationLink.ApiLink<ISnackbarMessageQueue>()
},
selectedIcon: PackIconKind.InformationCircle,
unselectedIcon: PackIconKind.InformationCircleOutline)
{
HorizontalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto
};
//懒加载转场画面
yield return new DemoItem(
"Transitions",
typeof(Transitions),
new[]
{
DocumentationLink.WikiLink("Transitions", "Transitions"),
DocumentationLink.DemoPageLink<Transitions>(),
DocumentationLink.ApiLink<Transitioner>("Transitions"),
DocumentationLink.ApiLink<TransitionerSlide>("Transitions"),
DocumentationLink.ApiLink<TransitioningContent>("Transitions"),
},
selectedIcon: PackIconKind.TransitionMasked,
unselectedIcon: PackIconKind.Transition);yield return new DemoItem(
//高度
"Elevation",
typeof(Elevation),
new[]
{
DocumentationLink.DemoPageLink<Elevation>(),
DocumentationLink.StyleLink("Shadows"),
DocumentationLink.SpecsLink("https://material.io/design/environment/elevation.html", "Elevation")
},
selectedIcon: PackIconKind.BoxShadow,
unselectedIcon: PackIconKind.BoxShadow);
}
/// <summary>
/// 菜单过滤函数
/// </summary>
/// <param name="obj">需要过滤动态数据菜单集合</param>
/// <returns>根据关键词筛选显示动态数据菜单集合</returns>
private bool DemoItemsFilter(object obj)
{
//关键词为空返回
if (string.IsNullOrWhiteSpace(_searchKeyword))
{
return true;
}
//返回符合菜单名包括关键词的菜单集合
return obj is DemoItem item
&& item.Name.ToLower().Contains(_searchKeyword!.ToLower());
}
九 总结
以上就是MaterialDesign中MainViewModel类的介绍,本文仅仅简单介绍了MainViewModel的示例使用,而实际使用时可以根据需求增添更多功能,只需要新建类继承该接口,均实现通知属性变更功能,双向绑定UI后,可自动即使更新UI显示,非常便捷高效。
十 下章预告
下一章我会教大家新的类