C# 在MVVM中使用CommandParameter传递类变量
我希望在单击视图中的按钮时传递ViewModel参数(类变量)。当指定字符串时,一切都会实现,但我需要从视图类传递一个非字符串值(functionAddNewField) Main.xaml:C# 在MVVM中使用CommandParameter传递类变量,c#,wpf,mvvm,C#,Wpf,Mvvm,我希望在单击视图中的按钮时传递ViewModel参数(类变量)。当指定字符串时,一切都会实现,但我需要从视图类传递一个非字符串值(functionAddNewField) Main.xaml: ... <Button x:Name="ButtonAddingField" CommandParameter="{Binding Path=Myprop}" Command="{Binding Path=Myprop, Re
...
<Button
x:Name="ButtonAddingField"
CommandParameter="{Binding Path=Myprop}"
Command="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}" />
...
...
private Color myprop;
public Color Myprop
{
get => myprop;
}
...
this.DataContext = new FieldCollectionViewModel(fields); // fields - List<*my Model*>
...
...
private DelegateCommand<object> addFieldCommand;
public ICommand AddFieldCommand {
get {
if (addFieldCommand == null) addFieldCommand = new DelegateCommand<object>(AddNewField);
return addFieldCommand;
}
}
private void AddNewField(object parameter)
{
// !!! parameter = ALWAYS NULL
}
...
。。。
...
Main.cs:
...
<Button
x:Name="ButtonAddingField"
CommandParameter="{Binding Path=Myprop}"
Command="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}" />
...
...
private Color myprop;
public Color Myprop
{
get => myprop;
}
...
this.DataContext = new FieldCollectionViewModel(fields); // fields - List<*my Model*>
...
...
private DelegateCommand<object> addFieldCommand;
public ICommand AddFieldCommand {
get {
if (addFieldCommand == null) addFieldCommand = new DelegateCommand<object>(AddNewField);
return addFieldCommand;
}
}
private void AddNewField(object parameter)
{
// !!! parameter = ALWAYS NULL
}
...
。。。
私人色彩;
公共颜色Myprop
{
get=>myprop;
}
...
this.DataContext=新的FieldCollectionViewModel(字段);//字段-列表
...
FieldCollectionViewModel.cs:
...
<Button
x:Name="ButtonAddingField"
CommandParameter="{Binding Path=Myprop}"
Command="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}" />
...
...
private Color myprop;
public Color Myprop
{
get => myprop;
}
...
this.DataContext = new FieldCollectionViewModel(fields); // fields - List<*my Model*>
...
...
private DelegateCommand<object> addFieldCommand;
public ICommand AddFieldCommand {
get {
if (addFieldCommand == null) addFieldCommand = new DelegateCommand<object>(AddNewField);
return addFieldCommand;
}
}
private void AddNewField(object parameter)
{
// !!! parameter = ALWAYS NULL
}
...
。。。
专用DelegateCommand addFieldCommand;
公共ICommand AddFieldCommand{
得到{
如果(addFieldCommand==null)addFieldCommand=new DelegateCommand(AddNewField);
返回addfield命令;
}
}
私有void AddNewField(对象参数)
{
//!!!参数=始终为空
}
...
和我的DelegateCommand.cs:
...
public class DelegateCommand<T> : ICommand
{
#region Constructors
/// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<T> executeMethod)
: this(executeMethod, null, false)
{
}
/// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod)
: this(executeMethod, canExecuteMethod, false)
{
}
/// <summary>
/// Constructor
/// </summary>
public DelegateCommand(Action<T> executeMethod, Func<T, bool> canExecuteMethod, bool isAutomaticRequeryDisabled)
{
if (executeMethod == null) throw new ArgumentNullException("executeMethod");
_executeMethod = executeMethod;
_canExecuteMethod = canExecuteMethod;
_isAutomaticRequeryDisabled = isAutomaticRequeryDisabled;
}
#endregion Constructors
#region Public Methods
/// <summary>
/// Method to determine if the command can be executed
/// </summary>
public bool CanExecute(T parameter)
{
if (_canExecuteMethod != null) return _canExecuteMethod(parameter);
return true;
}
/// <summary>
/// Execution of the command
/// </summary>
public void Execute(T parameter)
{
if (_executeMethod != null) _executeMethod(parameter);
}
/// <summary>
/// Raises the CanExecuteChaged event
/// </summary>
public void RaiseCanExecuteChanged()
{
OnCanExecuteChanged();
}
/// <summary>
/// Protected virtual method to raise CanExecuteChanged event
/// </summary>
protected virtual void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(_canExecuteChangedHandlers);
}
/// <summary>
/// Property to enable or disable CommandManager's automatic requery on this command
/// </summary>
public bool IsAutomaticRequeryDisabled {
get => _isAutomaticRequeryDisabled;
set {
if (_isAutomaticRequeryDisabled != value)
{
if (value)
CommandManagerHelper.RemoveHandlersFromRequerySuggested(_canExecuteChangedHandlers);
else
CommandManagerHelper.AddHandlersToRequerySuggested(_canExecuteChangedHandlers);
_isAutomaticRequeryDisabled = value;
}
}
}
#endregion Public Methods
#region ICommand Members
/// <summary>
/// ICommand.CanExecuteChanged implementation
/// </summary>
public event EventHandler CanExecuteChanged {
add {
if (!_isAutomaticRequeryDisabled) CommandManager.RequerySuggested += value;
CommandManagerHelper.AddWeakReferenceHandler(ref _canExecuteChangedHandlers, value, 2);
}
remove {
if (!_isAutomaticRequeryDisabled) CommandManager.RequerySuggested -= value;
CommandManagerHelper.RemoveWeakReferenceHandler(_canExecuteChangedHandlers, value);
}
}
bool ICommand.CanExecute(object parameter)
{
// if T is of value type and the parameter is not
// set yet, then return false if CanExecute delegate
// exists, else return true
if (parameter == null &&
typeof(T).IsValueType)
return _canExecuteMethod == null;
return CanExecute((T)parameter);
}
void ICommand.Execute(object parameter)
{
Execute((T)parameter);
}
#endregion ICommand Members
#region Data
private readonly Action<T> _executeMethod;
private readonly Func<T, bool> _canExecuteMethod;
private bool _isAutomaticRequeryDisabled;
private List<WeakReference> _canExecuteChangedHandlers;
#endregion Data
}
...
。。。
公共类DelegateCommand:ICommand
{
#区域构造函数
///
///建造师
///
公共DelegateCommand(Action executeMethod)
:此(executeMethod、null、false)
{
}
///
///建造师
///
公共DelegateCommand(Action executeMethod、Func canExecuteMethod)
:此(executeMethod、canExecuteMethod、false)
{
}
///
///建造师
///
public DelegateCommand(Action executeMethod、Func canExecuteMethod、bool IsAutomaticCrequeryDisabled)
{
如果(executeMethod==null)抛出新的ArgumentNullException(“executeMethod”);
_executeMethod=executeMethod;
_canExecuteMethod=canExecuteMethod;
_IsAutomaticCrequeryDisabled=IsAutomaticCrequeryDisabled;
}
#端域构造函数
#区域公共方法
///
///方法来确定是否可以执行该命令
///
公共布尔CanExecute(T参数)
{
if(_canExecuteMethod!=null)返回_canExecuteMethod(参数);
返回true;
}
///
///命令的执行
///
公共void执行(T参数)
{
如果(_executeMethod!=null)_executeMethod(参数);
}
///
///引发CanExecuteChaged事件
///
public void raisecancecutechanged()
{
OnCanExecuteChanged();
}
///
///用于引发CanExecuteChanged事件的受保护虚拟方法
///
受保护的虚拟void OnCanExecuteChanged()
{
CommandManagerHelper.CallWeakReferenceHandlers(\u canExecuteChangedHandlers);
}
///
///属性启用或禁用CommandManager对此命令的自动重新查询
///
公共图书馆被自动火化禁用{
get=>\已禁用自动火化;
设置{
如果(_IsAutomaticCrequeryDisabled!=值)
{
如果(值)
命令管理器删除建议的请求中的句柄(\u canExecuteChangedHandlers);
其他的
CommandManagerHelper.AddHandlersToRequerySuggested(\u canExecuteChangedHandlers);
_IsAutomaticCrequeryDisabled=值;
}
}
}
#端域公共方法
#区域ICommand成员
///
///ICommand.CanExecuteChanged实现
///
公共事件事件处理程序CanExecuteChanged{
加{
如果(!\u IsAutomaticCrequeryDisabled)CommandManager.RequerySuggested+=值;
CommandManagerHelper.AddWeakReferenceHandler(参考CanExecuteChangedHandler,值,2);
}
除去{
如果(!\u IsAutomaticCrequeryDisabled)CommandManager.RequerySuggested-=值;
CommandManagerHelper.RemoveWeakReferenceHandler(\u CanExecuteChangedHandler,值);
}
}
bool ICommand.CanExecute(对象参数)
{
//如果T是值类型,而参数不是
//尚未设置,如果CanExecute委托,则返回false
//存在,否则返回true
if(参数==null)&&
类型(T).IsValueType)
返回_canExecuteMethod==null;
返回CanExecute((T)参数);
}
void ICommand.Execute(对象参数)
{
执行((T)参数);
}
#endregion ICommand成员
#区域数据
私有只读操作_executeMethod;
私有只读函数可执行方法;
私人住宅被自动火化禁用;
私有列表\u CanexecuteChangedHandler;
#端域数据
}
...
我怎样才能解决我的问题
更新。
我更改了我的代码,现在它正在工作
多亏了@mm8
Myprop
必须是按钮的DataContext
的公共属性,您当前的绑定才能工作
如果它是父级UserControl
的属性,则可以使用相对资源绑定到它:
CommandParameter="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}"
请注意,您只能绑定到公共属性。无法绑定到字段。Myprop
必须是按钮的DataContext
的公共属性,当前绑定才能工作
如果它是父级UserControl
的属性,则可以使用相对资源绑定到它:
CommandParameter="{Binding Path=Myprop, RelativeSource={RelativeSource AncestorType=UserControl}}"
请注意,您只能绑定到公共属性。您不能绑定到字段。两个选项都不起作用:(我在我的帖子Main
a窗口中添加了一些代码?不,UserControl@RookieCPP:然后您需要将antestortype
设置为UserControl
。请参阅我的编辑。@RookieCPP:注意Myprop
必须是属性。两个选项都不起作用:(我在我的帖子Main
a窗口中添加了一些代码?不,UserControl@RookieCPP:然后您需要将antestortype
设置为UserControl
。请参阅我的编辑。@RookieCPP:注意Myprop
必须是属性。