C# WPF将动态生成的滑块绑定到函数

C# WPF将动态生成的滑块绑定到函数,c#,wpf,C#,Wpf,首先:不是的副本---是关于按钮的,中继命令无法传递我需要的参数 另外,不是重复的-这是一个没有参数的简单方法-与我的问题无关。 显然(但只是为了确保和避免巨魔)也不是这个的复制品。 现在,在清除这个问题之后(对不起,我真的很讨厌被不理解我的问题的人标记为“重复”),让我们谈谈这个问题::D 我正在尝试将生成的滑块(使用数据模板)绑定到事件(值已更改),我知道绑定事件是不可能的,我必须使用ICommand,但我不知道如何将事件参数获取到命令函数,这是与xaml相关的代码:(没有绑定,因为它不起作

首先:不是的副本---是关于按钮的,中继命令无法传递我需要的参数

另外,不是重复的-这是一个没有参数的简单方法-与我的问题无关。

显然(但只是为了确保和避免巨魔)也不是这个的复制品。

现在,在清除这个问题之后(对不起,我真的很讨厌被不理解我的问题的人标记为“重复”),让我们谈谈这个问题::D

我正在尝试将生成的滑块(使用数据模板)绑定到事件(值已更改),我知道绑定事件是不可能的,我必须使用ICommand,但我不知道如何将事件参数获取到命令函数,这是与xaml相关的代码:(没有绑定,因为它不起作用)


这就是我希望它绑定到的函数:

public void vibrationSlider_move(object Sender, RoutedPropertyChangedEventArgs<double> e)
        {
            VibrationValue = (byte)e.NewValue;
            SendPacket(cockpitType, (byte)Index.VibrationSlider, VibrationValue);
        }
公共无效振动滑块移动(对象发送方,RoutedPropertyChangedEventArgs e)
{
振动值=(字节)e.NewValue;
SendPacket(cockpitType,(字节)Index.可控滑块,可控值);
}
如您所见,我需要使用事件附带的“e”,我不知道如果不使用“ValueChanged”滑块事件,如何到达它

注:

请不要告诉我这样添加“ValueChanged”属性:

<Slider ValueChanged="VibrationSlider_move"/>

:)

它是使用DataTemplate和observableCollection生成的动态滑块,函数不在window.cs文件中,因此不可能仅使用事件


谢谢。

由于滑块是动态生成的,因此没有任何东西阻止您在以后添加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
}

代码隐藏:

<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
}
public主窗口()
{
初始化组件();
//最好不要让设计器执行自定义代码
if(DesignerProperties.GetIsInDesignMode(此))
返回;
slider.ValueChanged+=slider\u ValueChanged;
}
私有无效滑块\u值已更改(对象发送方,RoutedPropertyChangedEventArgs e)
{
//在这里做你的事
}

正如所指出的,在任何上下文中检查
设计模式都不简单。

由于滑块是动态生成的,因此没有任何东西可以阻止您在以后添加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
}

代码隐藏:

<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
}
public主窗口()
{
初始化组件();
//最好不要让设计器执行自定义代码
if(DesignerProperties.GetIsInDesignMode(此))
返回;
slider.ValueChanged+=slider\u ValueChanged;
}
私有无效滑块\u值已更改(对象发送方,RoutedPropertyChangedEventArgs e)
{
//在这里做你的事
}
如前所述,在任何上下文中检查
设计模式都不简单。

您可以使用工具箱,它允许将事件参数作为CommandParameter发送到ViewModel:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="ValueChanged">
        <cmd:EventToCommand Command="{Binding ValueChangedCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

在command.Execute方法中,您现在获得一个对象作为参数,您只需将其解析为正确的类型…

您可以使用工具箱,它允许将EventArgs作为CommandParameter发送到ViewModel:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="ValueChanged">
        <cmd:EventToCommand Command="{Binding ValueChangedCommand}" PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>


在command.Execute方法中,您现在得到一个对象作为参数,您只需将其解析为正确的类型…

正如@Philip W所述,您可以使用例如
MVVMLight
来帮助处理MVVM模式和手头的问题

例如,您可以使用
DataTemplate
Slider
创建一个
XAML
,如下所示:

<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>
这会给你类似的东西


正如@Philip W所述,您可以使用例如
MVVMLight
来帮助处理MVVM模式和手头的问题

例如,您可以使用
DataTemplate
Slider
创建一个
XAML
,如下所示:

<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>
这会给你类似的东西


您可以创建一个扩展

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;
        }
    }
}
公共部分类扩展
{
公共静态只读DependencyProperty ValueChangedCommand属性=DependencyProperty.RegisterAttached(“ValueChangedCommand”、typeof(ICommand)、typeof(Extensions)、new UIPropertyMetadata((s,e)=>
{
var元素=s作为滑块;
if(元素!=null)
{
element.ValueChanged-=OnSingleValueChanged;
如果(如NewValue!=null)
{
element.ValueChanged+=OnSingleValueChanged;
}
}
}));
公共静态ICommand GetValueChangedCommand(UIElement)
{
返回(ICommand)元素。GetValue(ValueChangedCommand属性);
}
公共静态无效SetValueChangedCommand(UIElement元素、ICommand值)
{
元素.SetValue(ValueChangedCommand属性,值);
}
SingleValueChanged上的私有静态无效(对象发送方,RoutedPropertyChangedEventArgs e)
{
var元素=发送方作为滑块;
var命令=element.GetValue(ValueChangedCommand属性)作为ICommand;
if(command!=null&&command.CanExecute(元素))
{
command.Execute(元素);
e、 已处理=正确;
}
}
}
然后可以在xaml中使用,如下所示

<Slider Minimum="0" Maximum="100" local:Extensions.ValueChangedCommand="{Binding ValueChangedCommand}"/>

您可以创建一个扩展

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;
        }
    }
}
公共部分类扩展
{
公共静态只读DependencyProperty ValueChangedCommand属性=DependencyProperty.RegisterAttached(“ValueChangedCommand”、typeof(ICommand)、typeof(Extensions)、new UIPropertyMetadata((s,e)=>
{
var元素=s作为滑块;
if(元素!=null)
{
element.ValueChanged-=OnSingleValueChanged;
如果(如NewValue!=null)
{
element.ValueChanged+=OnSingleValueChang