@Chubosaurus 소프트웨어 내가이 함께했다 당신의 접근 방식을 다음
내가 그것을 여기에 입력 할 너무 많은 코드 제작이 SO 자습서를 참조 단일 명령을 설정하고 CommandParameter을합니다. 여기
는
MenuFlyout
, 편집을 보여줄 것의 상황에 맞는 메뉴의 종류를 삭제 갖는
TextBlock
을 포함하는
DataTemplate
내부에 위치 할 일 항목의 목록에 결합
ListView
이다.
MenuFlyoutItem
에 뷰 모델의 명령을 결합 할 수있는 키는 ListView
이름을 지정하여 ListView에 이름을 가리 키도록 Command
에서 ElementName
속성을 사용하여 바인딩 요소를하는 것입니다. 우리의 뷰 모델의 명령에 액세스하기 위해 우리는 MenuFlyoutItem
의 DataContext
이 ItemsSource
의 항목은 MainPage.xaml을
<Page
x:Class="UWA.MenuFlyout.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWA.MenuFlyout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:UWA.MenuFlyout.ViewModels"
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
xmlns:common="using:UWA.MenuFlyout.Core"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Margin="24,24">
<ListView x:Name="Todos" ItemsSource="{Binding Todos}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Action}">
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem Text="edit"
Command="{Binding ElementName=Todos, Path=DataContext.EditTodo}"
CommandParameter="{Binding}"/>
<MenuFlyoutItem Text="delete"
Command="{Binding ElementName=Todos, Path=DataContext.DeleteTodo}"
CommandParameter="{Binding}"/>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Holding">
<common:OpenMenuFlyoutAction/>
</core:EventTriggerBehavior>
<core:EventTriggerBehavior EventName="RightTapped">
<common:OpenMenuFlyoutAction/>
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Page>
때문에 ListView에의
DataContext
을 가서의 명령에 바인딩했습니다
MainPage.xaml.cs는 MainPage의 DataContext가 설정된 곳입니다. ObservableCollection에 종류 및 EditTodo 및 DeleteTodo 명령 인 왜 그렇게 함유
namespace UWA.MenuFlyout
{
using UWA.MenuFlyout.ViewModels;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
this.DataContext = new MainViewModel();
}
/// <summary>
/// Invoked when this page is about to be displayed in a Frame.
/// </summary>
/// <param name="e">Event data that describes how this page was reached.
/// This parameter is typically used to configure the page.</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
// TODO: Prepare page for display here.
// TODO: If your application contains multiple pages, ensure that you are
// handling the hardware Back button by registering for the
// Windows.Phone.UI.Input.HardwareButtons.BackPressed event.
// If you are using the NavigationHelper provided by some templates,
// this event is handled for you.
}
}
}
MainViewModel.cs.
namespace UWA.MenuFlyout.ViewModels
{
using System.Collections.ObjectModel;
using System.Windows.Input;
using UWA.MenuFlyout.Core;
using UWA.MenuFlyout.Models;
public class MainViewModel : BaseViewModel
{
private ICommand editTodo;
private ICommand deleteTodo;
public MainViewModel()
{
this.Todos = new ObservableCollection<TodoModel>
{
new TodoModel { Id = 1, Action = "Buy Milk", IsDone = true },
new TodoModel { Id = 2, Action = "Buy Groceries", IsDone = false }
};
}
public ObservableCollection<TodoModel> Todos { get; set; }
public ICommand EditTodo
{
get
{
if (this.editTodo == null)
{
this.editTodo = new RelayCommand(this.OnEditTodo);
}
return this.editTodo;
}
}
public ICommand DeleteTodo
{
get
{
if (this.deleteTodo == null)
{
this.deleteTodo = new RelayCommand(this.OnDeleteTodo);
}
return this.deleteTodo;
}
}
public void OnEditTodo(object parameter)
{
// perform edit here
var todo = parameter as TodoModel;
}
public void OnDeleteTodo(object parameter)
{
// perform delete here
var todo = parameter as TodoModel;
}
}
}
모델
namespace UWA.MenuFlyout.Models
{
public class TodoModel
{
public int Id { get; set; }
public string Action { get; set; }
public bool IsDone { get; set; }
}
}
에서 INotifyPropertyChanged를 구현 BaseViewModel.
namespace UWA.MenuFlyout.Core
{
using System.ComponentModel;
using System.Runtime.CompilerServices;
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public virtual void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
간단한 ICommand 구현입니다. 및 DependencyObject에 IAction가 IAction 인터페이스의 실행 방법을 사용하여 MenuFlyout 열기를 구현
namespace UWA.MenuFlyout.Core
{
using System;
using System.Windows.Input;
public class RelayCommand : ICommand
{
private Action<object> action;
public RelayCommand(Action<object> action)
{
this.action = action;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
this.action(parameter);
}
}
}
OpenMenuFlyoutAction.
namespace UWA.MenuFlyout.Core
{
using Microsoft.Xaml.Interactivity;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls.Primitives;
public class OpenMenuFlyoutAction : DependencyObject, IAction
{
public object Execute(object sender, object parameter)
{
var frameworkElement = sender as FrameworkElement;
var flyoutBase = FlyoutBase.GetAttachedFlyout(frameworkElement);
flyoutBase.ShowAt(frameworkElement);
return null;
}
}
}
그 그리드는 경우' '당신이 명령 그런 식으로, 즉 당신이 당신의 ViewModel에 넣어 모든 모델에 대한 명령이 필요합니다 의미하는 것이라고 바인딩하고 있습니다. 그래서 "DvdRelease"를 어디에 두 었는지 명령이 있어야합니다. –
고마워, 내가 MVVM 디자인을 깰 수는 있지만 생각해 보겠다. 로직은 viewModel에 있어야하고 모델에는 없다. –
ViewModel에 있다면 더 좋을 것이다. 그런 식으로 구현하려는 경우 여기에서 수행하는 방법에 대한 자습서가 있습니다. http://stackoverflow.com/questions/25613212/how-to-implement-a-navigation-button-in-shared-application -resources/25627927 # 25627927 –