당신은 당신의 명령을 직접 쓸 수 있습니다.
다음은 내 명령에 사용하는 기본 클래스입니다.
인생을 더 편하게 해주는 아주 기본적인 것들이 있습니다.
- 는
Execute
방법은 객체를 받아, 그래서 당신은 당신이 당신의 명령에 작동합니다 사람 (이 대부분의 시간이다하는 ViewModel을 쉽게 전달 될 수
- 배열을 통과 할 수있을 것입니다 이 경우 필요없는 경우 스 와이프합니다.)
- 변경된 처리기가 CommandManager를 사용합니다. 이것은 매우 도움이됩니다.
아마도 몇 가지를 변경하고 싶을 것입니다. 제가 추가 한 것은 매우 도움이되기 때문입니다. (당신을 감안할 때
public class ExampleViewModel : PropertyChangedBase
{
public ExampleViewModel()
{
this.DoThisAndThatCommand = new ExampleCommand(this);
}
public CommandBase DoThisAndThatCommand { get; set; }
}
// and in XAML, you can use it like
<Button x:Name="Ok"
Command="{Binding DoThisAndThatCommand }" />
: (특히 뷰 모델)
public abstract class CommandBase : ICommand
{
public abstract bool CanExecute(object o);
public abstract void Execute(object o);
public PropertyChangedBase ViewModel { get; set; }
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
}
당신은 당신의 ViewModel에
public class ExampleCommand : CommandBase
{
public ExampleCommand (PropertyChangedBase viewModel)
{
this.ViewModel = viewModel;
}
public override void Execute(object o)
{
// something like
var settings = UnityContainer.Resolve<ISettings>();
settings.MagicValue = (this.ViewModel as ConcreteViewModel).MagicValue;
}
public override bool CanExecute(object o)
{
return true;
}
}
처럼 구현을 할 것이다, 당신은 특성을 갖는하여보기로 명령을 노출 의 DataContext
을 설정하여 ViewModel
과 View
을 올바로 연결 했음
이제 버튼을 클릭 할 때마다 명령 실행 메서드가 호출됩니다.
Command
에 ViewModel이 있으므로 쉽게 작업 할 수 있습니다.
명령 내에 또는 ViewModel
내부에 단추를 갖는 것은 매우 드뭅니다. MVVM에 대한 속임수는 ViewModel
에서 View
을 분리하고 ViewModel
에서 UIElements
을 가지지 않는 것입니다.
PropertyChangedBase (이 중 하나는 Caliburn.Micro와 함께 제공)가없는 경우 간단한 INotifyPropertyChanged 구현을 사용하는 것이 좋습니다.
I found this one here, should be german though
공공 추상 클래스 NotifyPropertyChangedBase는 : { # 지역 <에서 INotifyPropertyChanged> 회원
/// <summary>
/// Is connected to a method which handle changes to a property (located in the WPF Data Binding Engine)
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raise the [PropertyChanged] event
/// </summary>
/// <param name="propertyName">The name of the property</param>
protected void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
private Dictionary<string, object> propertyValueStorage;
#region Constructor
public NotifyPropertyChangedBase()
{
this.propertyValueStorage = new Dictionary<string, object>();
}
#endregion
/// <summary>
/// Set the value of the property and raise the [PropertyChanged] event
/// (only if the saved value and the new value are not equal)
/// </summary>
/// <typeparam name="T">The property type</typeparam>
/// <param name="property">The property as a lambda expression</param>
/// <param name="value">The new value of the property</param>
protected void SetValue<T>(Expression<Func<T>> property, T value)
{
LambdaExpression lambdaExpression = property as LambdaExpression;
if (lambdaExpression == null)
{
throw new ArgumentException("Invalid lambda expression", "Lambda expression return value can't be null");
}
string propertyName = this.getPropertyName(lambdaExpression);
T storedValue = this.getValue<T>(propertyName);
if (!object.Equals(storedValue, value))
{
this.propertyValueStorage[propertyName] = value;
this.OnPropertyChanged(propertyName);
}
}
/// <summary> Get the value of the property </summary>
/// <typeparam name="T">The property type</typeparam>
/// <param name="property">The property as a lambda expression</param>
/// <returns>The value of the given property (or the default value)</returns>
protected T GetValue<T>(Expression<Func<T>> property)
{
LambdaExpression lambdaExpression = property as LambdaExpression;
if (lambdaExpression == null)
{
throw new ArgumentException("Invalid lambda expression", "Lambda expression return value can't be null");
}
string propertyName = this.getPropertyName(lambdaExpression);
return getValue<T>(propertyName);
}
/// <summary>
/// Try to get the value from the internal dictionary of the given property name
/// </summary>
/// <typeparam name="T">The property type</typeparam>
/// <param name="propertyName">The name of the property</param>
/// <returns>Retrieve the value from the internal dictionary</returns>
private T getValue<T>(string propertyName)
{
object value;
if (propertyValueStorage.TryGetValue(propertyName, out value))
{
return (T)value;
}
else
{
return default(T);
}
}
/// <summary>
/// Extract the property name from a lambda expression
/// </summary>
/// <param name="lambdaExpression">The lambda expression with the property</param>
/// <returns>The extracted property name</returns>
private string getPropertyName(LambdaExpression lambdaExpression)
{
MemberExpression memberExpression;
if (lambdaExpression.Body is UnaryExpression)
{
var unaryExpression = lambdaExpression.Body as UnaryExpression;
memberExpression = unaryExpression.Operand as MemberExpression;
}
else
{
memberExpression = lambdaExpression.Body as MemberExpression;
}
return memberExpression.Member.Name;
}
}
아주 사용하기 쉬운을에서 INotifyPropertyChanged!
ViewModel에서 바인딩 에 대한 공용 속성 (매우 중요 함)을 제공하고 변경 알림을 시작해야합니다.
여기 INPC (에서 INotifyPropertyChanged)
public class LoginViewModel : NotifyPropertyChangedBase
{
public string UserName { get;set; }
}
이 INPC 구현이 당신을 위해 NotifyOfPropertyChange 호출을
의 기본 구현을 사용하는 방법의 예입니다, 당신은 걱정하지 않아도됩니다! 그러나 귀하의 사건에 가장 적합한 것을 조사해야합니다.
귀하의 질문에 이미 ViewModelBase가 있습니다. 아마 당신은 위의 것 대신이 것을 사용하기를 원할 것입니다.
정확히 달성하려는 내용을 상세하게 기재 해주십시오. –
@MareInfinitus, CommandParameter에 여러 매개 변수를 전달하려고합니다. 해당 매개 변수를 수집 할 수 없으며 컬렉션을 지원하지 않습니다 ... 위의 경우 .. 1/i의 경우에 ... 확인 ... 하지만 ICommand의 Execute 메소드에 i/p 매개 변수를 하나 이상 전달하려면 ... 막혔습니다 ... 미리 감사드립니다. – Amit
'i/p' 란 무엇입니까? 이 약어는 잘 알려져 있지 않습니다. "텍스트 말하기"를 이해할 수없는 우리를 돕기 위해 모든 단어를 철자하고 괄호 안에 약어를 기입하는 것이 가장 좋습니다. – user7116