Я только начал изучать MVVM, и я хочу знать, какой будет наилучшая практика, когда я захочу изменить содержимое из своего главного окна, когда я нажму кнопку внутри моего UserControl.
Это UserControl, который содержит кнопки, которые я буду нажимать. Когда я нажимаю на IconButtons, я получаю возможность изменить MainGrid на Grid, содержащую информацию из моей IconModel.
Для пояснения, я бы хотел, чтобы сетка показывала имя значка, описание, имя пользователя, пароль и имела кнопку, которая открывала бы либо программу, либо веб-сайт с использованием Path. Класс Icon находится внутри IconModel.cs, который размещен ниже.
IconView.xaml
<UserControl x:Class="ProgramManager.Views.IconView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ProgramManager"
xmlns:viewModel="clr-namespace:ProgramManager.ViewModel"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.DataContext>
<viewModel:IconViewModel/>
</UserControl.DataContext>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding Path = Icons}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Name="IconButton" Style="{StaticResource IconButtonStyle}" Content="{Binding Path = Initial, Mode = OneWay}" Click="Button_Click">
<Button.ToolTip>
<ToolTip Content="{Binding Path = Name, Mode = TwoWay}"/>
</Button.ToolTip>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</UserControl>
MainWindow.xaml
<Window x:Class="ProgramManager.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ProgramManager"
xmlns:views="clr-namespace:ProgramManager.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid Name="MainGrid" Grid.Column="1">
</Grid>
</Grid>
</Window>
Для справки, вот мои классы IconModel и IconViewModel.
IconModel.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Xml.Serialization;
namespace ProgramManager.Model
{
public class IconModel { }
[XmlRoot(ElementName = "Icons", IsNullable = true, DataType = "string")]
[XmlType(AnonymousType = true)]
[XmlInclude(typeof(ProgramIcon))]
[XmlInclude(typeof(WebsiteIcon))]
public class Icon : IComparable<Icon>, IComparer<Icon>, INotifyPropertyChanged
{
private string name;
private string description;
private string path;
private string username;
private string password;
[XmlElement("Name")]
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
RaisePropertyChanged("Name");
}
}
}
[XmlElement("Description")]
public string Description
{
get { return description; }
set
{
if (description != value)
{
description = value;
RaisePropertyChanged("Description");
}
}
}
[XmlElement("Path")]
public string Path
{
get { return path; }
set
{
if (path != value)
{
path = value;
RaisePropertyChanged("Path");
}
}
}
[XmlElement("Username")]
public string Username
{
get { return username; }
set
{
if (username != value)
{
username = value;
RaisePropertyChanged("Username");
}
}
}
[XmlElement("Password")]
public string Password
{
get { return password; }
set
{
if (password != value)
{
password = value;
RaisePropertyChanged("Password");
}
}
}
public string Initial {
get
{
return this.Name.Substring(0, 1).ToUpper();
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public int Compare(Icon x, Icon y)
{
return (x.Equals(null) || y.Equals(null)) ? 0 : x.CompareTo(y);
}
public int CompareTo(Icon other)
{
return string.Compare(this.Name, other.Name);
}
}
public class ProgramIcon : Icon { }
public class WebsiteIcon : Icon { }
}
IconViewModel.cs
using ProgramManager.Helpers;
using ProgramManager.Model;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
namespace ProgramManager.ViewModel
{
public class IconViewModel : INotifyPropertyChanged
{
private static readonly List<Icon> iconsList;
private ObservableCollection<Icon> icons;
public ObservableCollection<Icon> Icons
{
get { return icons; }
set
{
if (icons != value)
{
icons = value;
RaisePropertyChanged("Icons");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
public IconViewModel()
{
LoadIcons();
}
static IconViewModel()
{
if (!Directory.Exists(Constants.ResourcesDirectory))
{
Directory.CreateDirectory(Constants.ResourcesDirectory);
}
iconsList = XmlDataStorage.GetList<Icon>(Constants.IconsFilePath);
}
public void LoadIcons()
{
ObservableCollection<Icon> icons = new ObservableCollection<Icon>();
foreach(var icon in iconsList)
{
icons.Add(icon);
}
Icons = icons;
}
public void AddIcon(Icon icon)
{
iconsList.Add(icon);
iconsList.Sort();
XmlDataStorage.SaveToXml(Constants.IconsFilePath, iconsList);
LoadIcons();
}
}
}
Я попытался получить доступ к IconButton в MainWindow из IconView.xaml, но не могу понять, как это сделать.
Любая помощь приветствуется, спасибо!