创建任务栏






4.38/5 (7投票s)
在本教程中,我将解释如何使用 Merula Shell Library 在 C# 中创建 Windows 任务栏。

引言
在本教程中,我将解释如何使用 Merula Shell Library 在 C# 中创建 Windows 任务栏。
你可以在这里下载 Merula Shell Library.
首先,在 Visual Studio 中创建一个新项目。在新项目窗口中,选择 WPF 应用程序。将 Merula shell library 中的三个 DLL 添加到项目的引用中。
创建用户控件
对于每个窗口,我希望在我的任务栏中创建一个带有图像和标题的漂亮按钮。所以让我们创建一个用户控件,我将其命名为 TaskbarButton
。
<UserControl x:Class="DemoProject.TaskbarButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Name="imgIcon"/>
<TextBlock Name="lblTitle" Grid.Column="1" Margin="4" />
</Grid>
</UserControl>
在用户控件中,添加一个图像控件和一个文本块控件。
将以下代码添加到用户控件的代码隐藏文件中
using System;
using System.Windows.Controls;
using Window = MerulaShell.windows.Window;
namespace DemoProject
{
/// <summary>
/// Interaction logic for TaskbarButton.xaml
/// </summary>
public partial class TaskbarButton : UserControl
{
private readonly Window window;
//Constructor with a MerulaShell.windows.window as input
public TaskbarButton(Window window)
{
InitializeComponent();
this.window = window;
window.TitleChanged += WindowTitleChanged; //when the title of
//the window changes
SetProperties(); //set the window properties
}
private delegate void DelegateVoid();
void WindowTitleChanged(object sender, EventArgs e)
{
Dispatcher.Invoke(new DelegateVoid(SetTitle)); //invoke because
//merula shell runs in another thread
}
private void SetTitle()
{
lblTitle.Text = window.Title; // sets the title in the textblock
}
private void SetProperties()
{
imgIcon.Source = window.ProgramIcon; // sets the icon of the window
lblTitle.Text = window.Title; // sets the title in the textblock
}
}
}
你的用户控件现在看起来会像这样

加载窗口
下一步是在我们的任务栏中加载窗口。转到主窗口的 XAML 并将网格替换为 StackPanel。
我的主窗口 XAML 如下
<Window x:Class="DemoProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel Name="pnlTasks">
</StackPanel>
</Window>
将以下代码添加到主窗口的代码隐藏文件中
using System;
using System.Windows;
using MerulaShellController.ManageWindows;
namespace DemoProject
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ManageWindows windowManager;
public MainWindow()
{
InitializeComponent();
windowManager = new ManageWindows(); //create a new windowmanager
//only one needed
Closed += MainWindow_Closed; //on close event
windowManager.WindowListChanged += WindowManagerWindowListChanged; //when
//the list of windows is changed
LoadWindows(); //load the windows
}
private delegate void DelegateVoid();
void WindowManagerWindowListChanged(object sender, EventArgs e)
{
//invoke because merula shell runs in another thread
Dispatcher.Invoke(new DelegateVoid(LoadWindows));
}
void MainWindow_Closed(object sender, EventArgs e)
{
Environment.Exit(0); //stops the merula shell
}
private void LoadWindows()
{
ClearTasks(); //delete old tasks
var windows = windowManager.GetWindows();//windowManager.GetWindows()
//returns all the active windows
foreach (var window in windows)
{ //foreach window add a taskbar button
pnlTasks.Children.Add(new TaskbarButton(window));
}
}
private void ClearTasks() //delete old tasks
{
pnlTasks.Children.Clear();
}
}
}
结果是,我们现在有一个带有当前活动窗口的窗口。当窗口数量发生变化以及窗口的标题发生变化时,窗口列表将被更新。

使其可交互
你仍然无法与窗口进行交互,例如最小化或最大化它们。打开 TaskButton
用户控件。将一个 MouseUp
处理程序添加到用户控件标签中。
MouseUp="UserControlMouseUp"
将以下代码添加到用户控件的代码隐藏文件中
private bool active;
private void UserControlMouseUp
(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Background = Brushes.LightBlue; //set a nice active color
if(active) //when active minimize and maximize
window.MaximizeMinimize(); //minimize or maximize
else
{
active = true; //set active
window.SetToForeground(); //set window to foreground
}
InvokeActivated(new EventArgs());
}
public void SetNonActive()
{
active = false; //set active to false
Background = Brushes.White; //reset color to white
}
public event EventHandler Activated; //event to notify the mainwindow
public void InvokeActivated(EventArgs e)
{
EventHandler handler = Activated;
if (handler != null) handler(this, e);
}
你还需要编辑主窗口的代码隐藏文件。更改 LoadWindows()
方法
private void LoadWindows()
{
ClearTasks();//delete old tasks
var windows = windowManager.GetWindows(); //windowManager.GetWindows()
//returns all the active windows
foreach (var window in windows)
{ //foreach window add a taskbar button
var button = new TaskbarButton(window);
button.Activated += ButtonActivated; //add a event to the taskbarbutton
pnlTasks.Children.Add(button);
}
}
最后,你必须创建一个事件处理程序。将其添加到主窗口的代码隐藏文件中
void ButtonActivated(object sender, EventArgs e)
{
var senderButton = (TaskbarButton) sender; //the sender button
var otherButtons = pnlTasks.Children.OfType<TaskbarButton>().Where
(b => b != senderButton); //select the other buttons
foreach (var otherButton in otherButtons)
{
otherButton.SetNonActive(); //sets the other buttons to nonactive
}
}
结果是,你拥有一个可用的任务栏。
Merula Shell
有关 merula shell 的更多信息可以在以下链接中找到
历史
- 2011 年 6 月 3 日:初始发布