Как передать 2 параметра команде с помощью RelayCommand. Мне нужно передать COntrols в качестве параметров (сетка и окно). Я полностью осознаю, что такая проблема уже существовала в Stack Overflow, но я изо всех сил пытаюсь приспособить ее к своим потребностям.
Код 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;
}
}
И MultiValueConverter:
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();
}
}
Итак, я создал в ViewModel новый класс с двумя свойствами 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 StretchingModel
{
public Grid Grid { get; set; }
public Window Win { get; set; }
}
Да, я знаю, но я не использую элементы управления по их именам в коде программной части. Я имею в виду, что они передаются из представления в модель представления, а модель VieModel видит их как тип объекта, а затем преобразует их в соответствующие типы (сетка и окно). В любом случае, Биджан, не могли бы вы предложить свою идею, как бы вы сделали эту привязку?
идея - стандартный MVVM, где ВМ не знает о View. независимо от того, какой View вам нужно использовать для привязки, наверняка есть виртуальная машина, которую следует использовать. А для визуализации виртуальной машины, какой бы стиль или шаблон ни использовался для визуализации представления, в первую очередь можно использовать для визуализации привязанной виртуальной машины.
Хорошо, я попробую это сделать. Но что в случае диалоговых окон в MVVM? Мне нужно было бы использовать OpenFileDialog, чтобы я создал соответствующие классы в представлении, а затем использовал созданный класс OpenFileDialog из представления в XAML, чтобы установить значения свойств (например, Caption, Filter и т. д.) И привязать его к любой кнопке Command, которая будет запустить окно. И тогда мне также нужно было бы передать FilePath из представления в команду в ViewModel, которая будет обрабатывать открытие файла и как это сделать? Вы когда-нибудь работали с диалоговыми окнами в Xaml. Не могли бы вы мне намекнуть?
этот пост может помочь с OpenFileDialogstackoverflow.com/q/1619505/366064
Хорошо, спасибо, я тоже попробую. Если я не смогу решить эту проблему, я активирую проблему повторно.
Передача элемента управления и окна в модель просмотра - это не mvvm, поэтому ваше решение - просто делать то, что вы собираетесь делать в коде. Пахнет так, как будто вы переместили логику пользовательского интерфейса в модель представления. Это не MVVM. Логика представления принадлежит представлению внутри кода.





Передача Grid и Window в модель представления - это не MVVM ... модель представления не должна иметь никаких зависимостей от каких-либо элементов пользовательского интерфейса.
В любом случае, чтобы передать команде более одного значения, вы должны объединить два подхода. Конвертер должен вернуть экземпляр 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;
}
}
Итак, вы хотите привязать элементы управления к команде (что не одобряется и настоятельно не рекомендуется), и вы уже знаете ответ на заголовок своего вопроса. Я просто скажу использовать MVVM и не привязывать элементы управления ни к чему.