C# 如何删除正在更改其位置属性的窗口的焦点,以使主窗口不为';我没有堵住。WPF
我有一个窗口,它只显示一个图像和一个字符串。 如果超过5秒,我将通过更改其Top属性“淡出”窗口。如果发生这种情况,它会完全窃取我的主窗口的焦点,而我什么也做不了,因为主窗口被阻塞了。我用一些本地方法尝试过,但对我来说不起作用。是否有一种方法可以完全移除此窗口的焦点,以便在更改其他窗口的Top属性时,它不会窃取主窗口的焦点,也不会阻止它 UI xaml代码:C# 如何删除正在更改其位置属性的窗口的焦点,以使主窗口不为';我没有堵住。WPF,c#,wpf,C#,Wpf,我有一个窗口,它只显示一个图像和一个字符串。 如果超过5秒,我将通过更改其Top属性“淡出”窗口。如果发生这种情况,它会完全窃取我的主窗口的焦点,而我什么也做不了,因为主窗口被阻塞了。我用一些本地方法尝试过,但对我来说不起作用。是否有一种方法可以完全移除此窗口的焦点,以便在更改其他窗口的Top属性时,它不会窃取主窗口的焦点,也不会阻止它 UI xaml代码: <Window x:Class="Rikkachan.PlayedVideo" xmlns="http://sche
<Window x:Class="Rikkachan.PlayedVideo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PlayedVideo" Height="307" Width="542"
ResizeMode="NoResize" AllowsTransparency="True"
WindowStyle="None" Background="Transparent" ShowActivated="False">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Image Name="picBox" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="100"/>
<Label Name="lblPlayedVideo" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Opacity="100" Background="DimGray"/>
</Grid>
</Window>
查看WPF动画。您可以使用内置的WPF特性集而不是现有的代码来实现这一点。该功能集中包含动画开始和持续时间的计时器,该功能旨在比您自己的调度程序调用更好地管理UI焦点 这里有一个教程可以帮助您入门: 以下是对这些想法的基于代码(而不是基于XAML)的介绍: 以及官方文件。使图元淡入和淡出视图的教程可能特别适用
谢谢你的回答,我会看一下链接。我阅读了你的链接并做了一些更改,效果很好,如果它只是不透明度属性,如果动画更改Top属性,它会保持焦点并从主窗口窃取并阻止它,就像我以前的解决方案一样。有什么方法可以防止这种情况发生吗?当涉及到像这样的弹出式toast动画时,如果您更改Top属性,您将向操作系统发布消息,所以这并不奇怪。猜测一下,您可以在故事板上尝试Dispatcher.BeginInvoke(),并将优先级设置为
空闲
,这有可能工作,或者,您可以执行我必须执行的操作,并设置变换属性(而不是顶部属性)的动画。或者,将动画部分设置为一个较大的窗口或相同大小的边框(透明且无边框)。在该窗口内设置动画,并在情节提要完成后发布关闭命令。
public partial class PlayedVideo : Window
{
#region "Variables"
Rect workingArea = SystemParameters.WorkArea;
#endregion
#region "Initilizing"
public PlayedVideo()
{
InitializeComponent();
#region "Setting window at the lower right bottom"
this.EnableWindowMoving();
this.Left = workingArea.Right - this.Width;
this.Top = workingArea.Bottom - this.Height;
#endregion
picBox.Source = Screenshot.CreateScreenshotFromWindow("vlc").ToBitmapSource();
lblPlayedVideo.Content = "Media: " + PlayerProcessInformation.GetCurrentPlayedFile(SupportedPlayer.VLCMediaPlayer);
StartCloseTimer();
this.Closed += (sender, e) =>
{
Debug.WriteLine("I'm dead");
};
}
#endregion
#region "StartCloseTimer"
private void StartCloseTimer(double sec = 5)
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(sec);
timer.Tick += (sender, e) =>
{
for (double i = this.Top; i < workingArea.Bottom; i += 10, Opacity -= 0.099) // look if we get this smoother
{
this.Top = i;
Debug.WriteLine("Top: " + this.Top + "\r\nBottom: " + workingArea.Bottom);
Thread.Sleep(200);
}
timer.Stop();
Debug.WriteLine("Timer stopped, now I'm going to die!");
this.Close();
};
timer.Start();
}));
}
#endregion
}
<Window x:Class="Rikkachan.PlayedVideo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="PlayedVideo" Height="307" Width="542"
ResizeMode="NoResize" AllowsTransparency="True"
WindowStyle="None" Background="Transparent" ShowActivated="False"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<BeginStoryboard>
<Storyboard Name="storyBoardBegin" Completed="storyBoardBegin_Completed">
<DoubleAnimation AutoReverse="False" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:3" FillBehavior="HoldEnd" RepeatBehavior="1x" />
<DoubleAnimation AutoReverse="False" Storyboard.TargetProperty="Top" From="{Binding TopEnd}" To="{Binding TopBegin}" Duration="0:0:1" RepeatBehavior="1x"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Window.Triggers>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Image Name="picBox" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="100"/>
<Label Name="lblPlayedVideo" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="1" Opacity="100" Background="DimGray"/>
</Grid>
</Window>
public partial class PlayedVideo : Window
{
#region "Variables"
Rect workingArea = SystemParameters.WorkArea;
private bool closeStoryBoardCompleted = false;
private Window m_wnd = null;
//private Storyboard storyBoardBegin;
//private Storyboard storyBoardEnd;
#endregion
#region "Initilizing"
public PlayedVideo(Window wnd)
{
InitializeComponent();
m_wnd = wnd;
#region "Setting window at the lower right bottom"
this.EnableWindowMoving();
this.Left = workingArea.Right - this.Width;
this.Top = workingArea.Bottom - this.Height;
#endregion
StartCloseTimer();
this.Closed += (sender, e) =>
{
Debug.WriteLine("I'm dead");
};
}
#endregion
#region "StartCloseTimer"
private void StartCloseTimer(double sec = 5)
{
Task.Run(() =>
{
this.Dispatcher.BeginInvoke((Action)(() =>
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(sec);
timer.Tick += (sender, e) =>
{
if (!closeStoryBoardCompleted)
{
DoubleAnimation animation = new DoubleAnimation(0, (Duration)TimeSpan.FromSeconds(sec));
DoubleAnimation animation2 = new DoubleAnimation(workingArea.Bottom, (Duration)TimeSpan.FromSeconds(sec));
m_wnd.Focus();
animation.Completed += (s, _) =>
{
Debug.WriteLine("Timer stopped, now I'm going to die!");
this.Close();
};
this.BeginAnimation(UIElement.OpacityProperty, animation);
this.BeginAnimation(Window.TopProperty, animation2);
}
};
timer.Start();
}));
});
}
#endregion
private void storyBoardBegin_Completed(object sender, EventArgs e)
{
picBox.Source = Screenshot.CreateScreenshotFromWindow("vlc").ToBitmapSource();
lblPlayedVideo.Content = "Media: " + PlayerProcessInformation.GetCurrentPlayedFile(SupportedPlayer.VLCMediaPlayer);
}
public double TopBegin{get { return workingArea.Bottom - this.Height; }}
public double TopEnd { get { return workingArea.Bottom; } }
}