我有一个带有Slider的 PlayerV.xaml 视图:
<Slider Value="{Binding CurrentProgress}"/>
并有一个按钮:
<Button Content="next song" Command="{Binding playNext}"/>
按钮工作正常。按钮的 playNext 命令包含在 PlayerVM.cs
中我希望使用滑块的ValueChanged来调用存储在 PlayerVM.cs 中的函数:
[1]:<Slider Value="{Binding CurrentProgress}" ValueChanged="{Binding playNext}"/>
我知道[1]的语法不正确,为了清楚起见,我使用了它。
====附加说明====
我知道我可以写:
<Slider ValueChanged="Slider_ValueChanged" Value="{Binding CurrentProgress}" />
在 PlayerV.xaml.cs 中会有
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
//some logic (actions)
}
}
但我不想在那里有任何逻辑。我希望它在 PlayerVM.cs (就像按钮的命令处理函数)。 怎么做? 我的App.xaml.cs启动函数也是:
private void OnStartup(object sender, StartupEventArgs e)
{
MainWindow _mainWindow = new MainWindow();
PlayerVM playerVM = new PlayerVM();
_mainWindow.DataContext = playerVM;
_mainWindow.Show();
}
答案 0 :(得分:10)
您有两种选择。首先,尽管您所说的不想使用代码,但一个解决方案就是让您做到这一点。在ValueChanged
事件处理程序中,只要更改值,就可以调用视图模型方法:
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Slider slider = sender as Slider;
PlayerVM viewModel = (PlayerVM)DataContext;
viewModel.YourMethod(slider.Value);
}
我提供了这个解决方案,因为我怀疑你是MVVM的新手并且仍然认为你不允许使用后面的代码。事实上,这根本就不是 的情况,对于像这样的纯粹的UI问题,它是一个很好的地方。
另一种选择是将数据直接绑定到Slider.Value
。随着Slider
值的更改,属性也将更改。因此,您只需从数据绑定属性设置器中调用您的方法:
public double CurrentProgress
{
get { return currentProgress; }
set
{
currentProgress = value;
NotifyPropertyChanged("CurrentProgress");
YourMethod(value);
}
}
另一个选项涉及在自定义附加属性中处理ValueChanged
事件。这个解决方案比其他解决方案还要多一点,所以我更倾向于指导你为其他问题编写的一些答案,而不是重新编写它。有关此方法的说明和代码示例,请参阅我对How to set Focus to a WPF Control using MVVM?和WPF C# - navigate WebBrowser on mouseclick through Binding问题的回答。
答案 1 :(得分:3)
通过使用事件来表示逻辑,您可以将事件绑定到视图模型,但是您需要帮助。您需要使用System.Windows.Interactivity命名空间中的函数并包含MVVM Light(可能有其他MVVM库具有该功能但我使用MVVM Light)。
请参阅:Is it possible to bind a WPF Event to MVVM ViewModel command?