WPF MVVM Multibinding - 如何使用 RelayCommand 将两个参数传递给 Command
WPF MVVM Multibinding - How to pass two parameters to Command using RelayCommand
如何使用 RelayCommand 将 2 个参数传递给命令。我需要将控件作为参数传递(网格和 Window)。我完全知道 Stack Overflow 上已经存在此类问题,但我正在努力根据自己的需要进行调整。
- 看看我的第一次尝试如下。它显然不起作用,因为中继无法获得 2 个参数。
Xaml代码:
<Button Name="StretchScreenBtn" Content="Stretch screen" DataContext=" {StaticResource CommandWindow}" Command="{Binding ResizeScreenCommand}"
Width="100" Height="50">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource CommandParamsConv}">
<Binding ElementName="ScreenGrid" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</Button.CommandParameter>
</Button>
来自 ViewModel 的命令代码:
private ICommand _ResizeScreenCommand;
public ICommand ResizeScreenCommand
{
get
{
if (_ResizeScreenCommand == null)
{
_ResizeScreenCommand = new RelayCommand(
(argument1, argument2) =>
{
Grid grid = argument1 as Grid;
Window window = argument2 as Window;
if ((int)grid.GetValue(Grid.ColumnSpanProperty) == 2)
{
grid.SetValue(Grid.ColumnSpanProperty, 1);
window.WindowStyle = WindowStyle.None;
}
else
{
grid.SetValue(Grid.ColumnSpanProperty, 2);
window.WindowStyle = WindowStyle.SingleBorderWindow;
}
}
);
}
return _ResizeScreenCommand;
}
}
和多值转换器:
class CommandParamsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
object[] parameters = values;
return parameters;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
- 我的第二次尝试是按照 How to Passing multiple parameters RelayCommand?
中的解决方案
因此,我在 ViewModel 中创建了新的 class,具有两个属性 Grid 和 Window 类型,然后尝试将 xaml 元素绑定到这些属性。但在这种情况下,编译器会抱怨这些属性是非依赖性的,无法绑定。
请给我任何解决方法的提示?
下面是修改后的xaml代码:
<Button Name="StretchScreenBtn" Content="Stretch screen" DataContext="{StaticResource CommandWindow}" Command="{Binding ResizeScreenCommand}"
Width="100" Height="50">
<Button.CommandParameter>
<vm:StretchingModel Grid="{Binding ElementName=ScreenGrid}" Win="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
</Button.CommandParameter>
</Button>
ViewModel 中的附加 class:
class StretchingModel
{
public Grid Grid { get; set; }
public Window Win { get; set; }
}
将 Grid
和 Window
传递给视图模型不是 MVVM...视图模型不应依赖任何 UI 元素。
无论如何,要将多个值传递给命令,您应该结合使用两种方法。转换器应该 return 一个 StretchingModel
:
的实例
class CommandParamsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new StretchingModel() { Grid = values[0], Window = values[1] };
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
...命令接受:
private ICommand _ResizeScreenCommand;
public ICommand ResizeScreenCommand
{
get
{
if (_ResizeScreenCommand == null)
{
_ResizeScreenCommand = new RelayCommand(
(argument) =>
{
StretchingModel model = argument as StretchingModel;
...
}
);
}
return _ResizeScreenCommand;
}
}
如何使用 RelayCommand 将 2 个参数传递给命令。我需要将控件作为参数传递(网格和 Window)。我完全知道 Stack Overflow 上已经存在此类问题,但我正在努力根据自己的需要进行调整。
- 看看我的第一次尝试如下。它显然不起作用,因为中继无法获得 2 个参数。
Xaml代码:
<Button Name="StretchScreenBtn" Content="Stretch screen" DataContext=" {StaticResource CommandWindow}" Command="{Binding ResizeScreenCommand}"
Width="100" Height="50">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource CommandParamsConv}">
<Binding ElementName="ScreenGrid" />
<Binding RelativeSource="{RelativeSource AncestorType=Window}" />
</MultiBinding>
</Button.CommandParameter>
</Button>
来自 ViewModel 的命令代码:
private ICommand _ResizeScreenCommand;
public ICommand ResizeScreenCommand
{
get
{
if (_ResizeScreenCommand == null)
{
_ResizeScreenCommand = new RelayCommand(
(argument1, argument2) =>
{
Grid grid = argument1 as Grid;
Window window = argument2 as Window;
if ((int)grid.GetValue(Grid.ColumnSpanProperty) == 2)
{
grid.SetValue(Grid.ColumnSpanProperty, 1);
window.WindowStyle = WindowStyle.None;
}
else
{
grid.SetValue(Grid.ColumnSpanProperty, 2);
window.WindowStyle = WindowStyle.SingleBorderWindow;
}
}
);
}
return _ResizeScreenCommand;
}
}
和多值转换器:
class CommandParamsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
object[] parameters = values;
return parameters;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
- 我的第二次尝试是按照 How to Passing multiple parameters RelayCommand? 中的解决方案
因此,我在 ViewModel 中创建了新的 class,具有两个属性 Grid 和 Window 类型,然后尝试将 xaml 元素绑定到这些属性。但在这种情况下,编译器会抱怨这些属性是非依赖性的,无法绑定。
请给我任何解决方法的提示?
下面是修改后的xaml代码:
<Button Name="StretchScreenBtn" Content="Stretch screen" DataContext="{StaticResource CommandWindow}" Command="{Binding ResizeScreenCommand}"
Width="100" Height="50">
<Button.CommandParameter>
<vm:StretchingModel Grid="{Binding ElementName=ScreenGrid}" Win="{Binding RelativeSource={RelativeSource AncestorType=Window}}" />
</Button.CommandParameter>
</Button>
ViewModel 中的附加 class:
class StretchingModel
{
public Grid Grid { get; set; }
public Window Win { get; set; }
}
将 Grid
和 Window
传递给视图模型不是 MVVM...视图模型不应依赖任何 UI 元素。
无论如何,要将多个值传递给命令,您应该结合使用两种方法。转换器应该 return 一个 StretchingModel
:
class CommandParamsConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return new StretchingModel() { Grid = values[0], Window = values[1] };
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
...命令接受:
private ICommand _ResizeScreenCommand;
public ICommand ResizeScreenCommand
{
get
{
if (_ResizeScreenCommand == null)
{
_ResizeScreenCommand = new RelayCommand(
(argument) =>
{
StretchingModel model = argument as StretchingModel;
...
}
);
}
return _ResizeScreenCommand;
}
}