Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在循环过程中按下捕捉按钮_C#_Wpf - Fatal编程技术网

C# 在循环过程中按下捕捉按钮

C# 在循环过程中按下捕捉按钮,c#,wpf,C#,Wpf,我有一个WPF应用程序,它使用MediaElement。 我想循环视频的某个部分。我有一个StartTime和EndTime变量用于循环。为了循环,我尝试了dispatchermer,但是对于小于1秒的循环来说,它太慢了。所以我尝试了简单的while循环,如下所示 while (true) { if(!buttonPressed) { while (mePlayer.Position < loop.EndTime) ; //go till end o

我有一个WPF应用程序,它使用
MediaElement
。 我想循环视频的某个部分。我有一个
StartTime
EndTime
变量用于循环。为了循环,我尝试了
dispatchermer
,但是对于小于1秒的循环来说,它太慢了。所以我尝试了简单的while循环,如下所示

while (true)
{
     if(!buttonPressed)
     {
          while (mePlayer.Position < loop.EndTime) ; //go till end of loop
          mePlayer.Position = loop.StartTime; //after reaching end of loop  start again
     }
}
while(true)
{
如果(!按钮按下)
{
while(mePlayer.Position
使用上述代码,即使是0.5秒的视频循环也可以正常运行,但是
上述方法的问题是,一旦它进入无限循环,它就无法检测到按钮按下,因此我无法停止循环。因此,我的问题是,如何检测while循环中的按钮按下,以便我停止循环视频并继续执行其他任务?

我很惊讶您无法获得有关视频播放进度的任何信息。但是您可以通过组合
任务
调度程序
(因为跨线程)来解决这个问题,而不阻塞UI,如下所示

MainWindow.xaml.cs

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private CancellationTokenSource _tokenSource;
    private double _start;
    private double _stop;

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;

        media.LoadedBehavior = MediaState.Manual;
        Start = 0;

        media.MediaOpened += (sender, args) =>
        {
            Stop = (int)media.NaturalDuration.TimeSpan.TotalSeconds;
            SetEndPosition();
        };
        media.Source = new Uri("video.wmv", UriKind.Relative);
        media.Play();
    }

    private async void SetEndPosition()
    {
        _tokenSource?.Cancel();
        _tokenSource = new CancellationTokenSource();
        var token = _tokenSource.Token;

        await Task.Run(() =>
        {
            if (token.IsCancellationRequested)
                return;

            while (!token.IsCancellationRequested)
            {
                Dispatcher.Invoke(() =>
                {
                    double position = media.Position.TotalSeconds;
                    if (position >= Stop)
                        SetStartPosition();
                });
                Thread.Sleep(100);
            }
        }, token);
    }

    private void SetStartPosition()
    {
        media.Position = TimeSpan.FromSeconds(Start);
    }

    public double Start
    {
        get { return _start; }
        set { _start = value; OnPropertyChanged(); SetStartPosition(); }
    }

    public double Stop
    {
        get { return _stop; }
        set { _stop = value; OnPropertyChanged(); }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}
main window.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"
        mc:Ignorable="d"
        Title="MainWindow" 
        Height="422" 
        Width="450">
<Grid Margin="10">
    <Grid.RowDefinitions>
        <RowDefinition Height="340" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>

    <MediaElement Grid.Row="0" Grid.ColumnSpan="2" Margin="0,0,0,10" x:Name="media" />
    <TextBox Grid.Row="1" Grid.Column="0" Text="{Binding Start}"></TextBox>
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Stop}"></TextBox>
</Grid>


为什么不捕获事件/检测绑定属性中的更改,而不是循环?我没有检查,但肯定玩家有位置更改事件或类似的事件。我只是检查了一下,没有发现任何位置更改事件。为什么不让代理
异步
等待任务。延迟(TimeSpan.frommissions(100))
?根本没有理由阻止线程。上面的代码在循环中运行良好。但是如果我想从A点到B点播放视频,A点和B点是用户输入,该怎么办呢。在本例中,我尝试将bot开始时间和结束时间设置为相同,但在这种情况下不起作用。工作正常,我更新了代码。请注意,您需要对“真实生活”应用程序进行一些修改。现在运行良好。谢谢Mikko Viitala。