|
一、metro项目中使用MVVM 模式的实例
以及使用Popup 来模拟实现Modal Dialogs
1.DelegateCommand类 继承ICommand接口
View Code
namespace System.Windows.Input
{
// 摘要:
// 定义一个命令
public interface ICommand
{
// 摘要:
// 当出现影响是否应执行该命令的更改时发生。
event EventHandler CanExecuteChanged;
// 摘要:
// 定义用于确定此命令是否可以在其当前状态下执行的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。 如果此命令不需要传递数据,则该对象可以设置为 null。
//
// 返回结果:
// 如果可以执行此命令,则为 true;否则为 false。
bool CanExecute(object parameter);
//
// 摘要:
// 定义在调用此命令时调用的方法。
//
// 参数:
// parameter:
// 此命令使用的数据。 如果此命令不需要传递数据,则该对象可以设置为 null。
void Execute(object parameter);
}
}
internal class DelegateCommand : ICommand
{
private readonly Action _execute;
private readonly Func _canExecute;
///
/// Initializes a new instance of the DelegateCommand class that
/// can always execute.
///
/// The execution logic.
/// If the execute argument is null.
public DelegateCommand(Action execute)
: this(execute, null)
{
}
///
/// Initializes a new instance of the DelegateCommand class.
///
/// The execution logic.
/// The execution status logic.
/// If the execute argument is null.
public DelegateCommand(Action execute, Func canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
_execute = execute;
_canExecute = canExecute;
}
///
/// Occurs when changes occur that affect whether the command should execute.
///
public event EventHandler CanExecuteChanged;
///
/// Raises the event.
///
[SuppressMessage("Microsoft.Design", "CA1030:UseEventsWhereAppropriate",
Justification = "This cannot be an event")]
public void RaiseCanExecuteChanged()
{
var handler = CanExecuteChanged;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
///
/// Defines the method that determines whether the command can execute in its current state.
///
/// This parameter will always be ignored.
/// true if this command can be executed; otherwise, false.
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute();
}
///
/// Defines the method to be called when the command is invoked.
///
/// This parameter will always be ignored.
public void Execute(object parameter)
{
if (CanExecute(parameter))
{
_execute();
}
}
}
Models部分:
PinkFerrari 类继承BindableBase 类
public class PinkFerrari : BindableBase
{
private string name;
private bool isSelected;
public string Name
{
get { return name; }
set { this.SetProperty(ref name, value); }
}
public string ImagePath { get; set; }
public ImageSource Image
{
get
{
return new BitmapImage(new Uri("ms-appx:///" + this.ImagePath));
}
}
public bool IsSelected
{
get { return isSelected; }
set { this.SetProperty(ref isSelected, value); }
}
}
ViewModels 部分:
CatalogViewModel 类和 MainPageViewModel 类
public class CatalogViewModel : BindableBase
{
private ObservableCollection cars = new ObservableCollection()
{
new PinkFerrari{Name = "Enzo", ImagePath=@"Assets/Images/Enzo.jpg"},
new PinkFerrari{Name = "458 Italia", ImagePath=@"Assets/Images/Italia.jpg"},
new PinkFerrari{Name = "California", ImagePath=@"Assets/Images/California.jpg"},
new PinkFerrari{Name = "430", ImagePath=@"Assets/Images/430.jpg"},
new PinkFerrari{Name = "360 Sbarro", ImagePath=@"Assets/Images/Sbarro.jpg"},
new PinkFerrari{Name = "Scuderia Spider", ImagePath=@"Assets/Images/Spider.jpg"},
new PinkFerrari{Name = "599 GTO", ImagePath=@"Assets/Images/599.jpg"}
};
public ObservableCollection Cars
{
get { return cars; }
}
}
public class MainPageViewModel : BindableBase
{
private ICommand openDialogCommand;
private Popup catalogPopup;
private CatalogViewModel catalogViewModel;
private ObservableCollection shoppingList = new ObservableCollection();
public MainPageViewModel()
{
this.openDialogCommand = new DelegateCommand(this.OpenDialog_Executed);
}
public ICommand OpenDialogCommand
{
get { return this.openDialogCommand; }
}
public ObservableCollection ShoppingList
{
get { return this.shoppingList; }
}
private void OpenDialog_Executed()
{
catalogViewModel = new CatalogViewModel();
CatalogDialog dialog = new CatalogDialog();
dialog.DataContext = catalogViewModel;
dialog.CloseRequested += Dialog_CloseRequested;
this.catalogPopup = new Popup();
this.catalogPopup.Child = dialog;
this.catalogPopup.IsOpen = true;
}
private void Dialog_CloseRequested(object sender, EventArgs e)
{
this.catalogPopup.IsOpen = false;
this.shoppingList.Clear();
var query = catalogViewModel.Cars.Where(p => p.IsSelected);
foreach (var item in query)
{
this.shoppingList.Add(item);
}
}
}
Views 部分:
CatalogDialog.xaml 、CatalogDialog.xaml.cs
和MainPage.xaml 、MainPage.xaml.cs
public sealed partial class CatalogDialog : Page
{
public event EventHandler CloseRequested;
public CatalogDialog()
{
this.InitializeComponent();
var bounds = Window.Current.Bounds;
this.RootPanel.Width = bounds.Width;
this.RootPanel.Height = bounds.Height;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
if (this.CloseRequested != null)
{
this.CloseRequested(this, EventArgs.Empty);
}
}
private void CatalogGridView_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
foreach (var item in e.AddedItems)
{
PinkFerrari pf = item as PinkFerrari;
pf.IsSelected = true;
}
foreach (var item in e.RemovedItems)
{
PinkFerrari pf = item as PinkFerrari;
pf.IsSelected = false;
}
}
}
文章来源:http://blogs.u2u.be/diederik |
|