我有一个 PlayerV.xaml View ,里面有一个滑块:
<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();
}
最佳答案
你有两个选择。首先,尽管您说不想使用代码隐藏,但一个解决方案是让您这样做。在 ValueChanged
事件处理程序中,您可以在值更改时简单地调用您的 View 模型方法:
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
Slider slider = sender as Slider;
PlayerVM viewModel = (PlayerVM)DataContext;
viewModel.YourMethod(slider.Value);
}
我提供此解决方案是因为我怀疑您是 MVVM 的新手,并且仍然认为您不允许使用背后的代码。事实上,情况完全不是这样,对于像这样的纯粹 UI 问题,这是一个很好的地方。
另一种选择是直接将属性数据绑定(bind)到
Slider.Value
。随着 Slider
值更改,属性也将更改。因此,您可以简单地从数据绑定(bind)属性 setter 调用您的方法: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 问题的回答以获取此方法的说明和代码示例。关于c# - 如何处理 View 模型中的 Slider.ValueChanged 事件?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25138695/