第一:不是Binding Button click to a method的重复---它是关于按钮的,而Relay命令无法传递我需要的参数
此外,不是How do you bind a Button Command to a member method?的副本 - 这是一个没有参数的简单方法 - 与我的问题无关。
显然(但只是为了确保并避免使用巨魔)并非Silverlight MVVM: where did my (object sender, RoutedEventArgs e) go?的重复。
现在清除了这个(抱歉,我真的厌倦了被不理解我的问题的人标记为“重复”),让我们谈谈这个问题::D
我正在尝试将生成的滑块(使用数据模板)绑定到事件(值已更改),我知道绑定事件是不可能的,我必须使用ICommand,但我不知道如何获取事件参数对于命令函数,这是xaml相关代码:(没有绑定,因为它不起作用)
<Slider Grid.Column="1" Grid.Row="1" Height="30" IsSnapToTickEnabled="True" Maximum="100" SmallChange="1" IsMoveToPointEnabled="True"/>
这是我希望它绑定到的功能:
public void vibrationSlider_move(object Sender, RoutedPropertyChangedEventArgs<double> e)
{
VibrationValue = (byte)e.NewValue;
SendPacket(cockpitType, (byte)Index.VibrationSlider, VibrationValue);
}
正如您所看到的,我需要使用事件附带的'e',我不知道如何在不使用“ValueChanged”滑块事件的情况下使用它。
注意:
请不要告诉我添加“ValueChanged”属性,如下所示:
<Slider ValueChanged="VibrationSlider_move"/>
:)
这是一个生成的动态滑块,使用带有observableCollection的DataTemplate,该函数不在window.cs文件中,因此无法使用事件。
谢谢。
答案 0 :(得分:4)
您可以使用MVVMLight工具包,它允许将EventArgs作为CommandParameter发送到ViewModel:
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<cmd:EventToCommand Command="{Binding ValueChangedCommand}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
在你的command.Execute方法中,你现在得到一个对象作为参数,你只需要解析为正确的类型......
答案 1 :(得分:2)
正如@Philip W所说,你可以使用例如MVVMLight
帮助处理MVVM模式和手头的问题。
例如,您可以XAML
DataTemplate
和Slider
,如下所示:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
mc:Ignorable="d"
Title="MainWindow"
Height="250"
Width="250">
<Window.Resources>
<DataTemplate x:Key="SomeTemplate">
<StackPanel Margin="15">
<!-- Wrong DataContext can drive you mad!1 -->
<StackPanel.DataContext>
<local:SomeTemplateViewModel />
</StackPanel.DataContext>
<TextBlock Text="This is some template"/>
<Slider
Height="30"
IsSnapToTickEnabled="True"
Maximum="100"
SmallChange="1"
IsMoveToPointEnabled="True">
<!-- Bind/pass event as command -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="ValueChanged">
<command:EventToCommand
Command="{Binding Mode=OneWay, Path=ValueChangedCommand}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Slider>
<!-- Show current value, just for sake of it... -->
<TextBlock
Text="{Binding Value}"
FontWeight="Bold"
FontSize="24">
</TextBlock>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ContentControl ContentTemplate="{StaticResource SomeTemplate}" />
</Window>
所以基本上你将所需的event
绑定到名为Command
并将EventArgs
作为参数传递给它。然后在ViewModel
中,作为滑块的DataContext
,您可以处理事件传递给命令。
public class SomeTemplateViewModel : ViewModelBase
{
private double _value;
public SomeTemplateViewModel()
{
// Create command setting Value as Slider's NewValue
ValueChangedCommand = new RelayCommand<RoutedPropertyChangedEventArgs<double>>(
args => Value = args.NewValue);
}
public ICommand ValueChangedCommand { get; set; }
public double Value
{
get { return _value; }
set { _value = value; RaisePropertyChanged(); } // Notify UI
}
}
这会给你类似的东西。
答案 2 :(得分:2)
您可以创建扩展程序
MAIL_DRIVER=smtp
MAIL_HOST=XXXX.XXXX.in
MAIL_PORT=587
MAIL_USERNAME=dexxxxx
MAIL_PASSWORD=XXXXXXXX
MAIL_ENCRYPTION=tls
然后可以在xaml中使用,如下所示。
public partial class Extensions
{
public static readonly DependencyProperty ValueChangedCommandProperty = DependencyProperty.RegisterAttached("ValueChangedCommand", typeof(ICommand), typeof(Extensions), new UIPropertyMetadata((s, e) =>
{
var element = s as Slider;
if (element != null)
{
element.ValueChanged -= OnSingleValueChanged;
if (e.NewValue != null)
{
element.ValueChanged += OnSingleValueChanged;
}
}
}));
public static ICommand GetValueChangedCommand(UIElement element)
{
return (ICommand)element.GetValue(ValueChangedCommandProperty);
}
public static void SetValueChangedCommand(UIElement element, ICommand value)
{
element.SetValue(ValueChangedCommandProperty, value);
}
private static void OnSingleValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
var element = sender as Slider;
var command = element.GetValue(ValueChangedCommandProperty) as ICommand;
if (command != null && command.CanExecute(element))
{
command.Execute(element);
e.Handled = true;
}
}
}
答案 3 :(得分:0)
由于您的滑块是动态生成的,因此不会阻止您以后添加ValueChanged事件:
<强> XAML:强>
<Slider x:Name="slider" HorizontalAlignment="Left" Margin="10,143,0,0" VerticalAlignment="Top" Width="474" Grid.ColumnSpan="2" />
<强>代码隐藏:强>
public MainWindow()
{
InitializeComponent();
// it is a good idea to not allow designer to execute custom code
if (DesignerProperties.GetIsInDesignMode(this))
return;
slider.ValueChanged += Slider_ValueChanged;
}
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
// do your stuff here
}
在任何情况下检查design mode
并不简单,如here所述。