178 lines
6.7 KiB
C#
178 lines
6.7 KiB
C#
// Copyright (c) 2017 schick Informatik
|
|
// Description: Custom tab item
|
|
//
|
|
|
|
using System;
|
|
using System.ComponentModel;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Animation;
|
|
using System.Windows.Threading;
|
|
|
|
namespace ENI2.Controls
|
|
{
|
|
/// <summary>
|
|
/// Follow steps 1a or 1b and then 2 to use this custom control in a XAML file.
|
|
///
|
|
/// Step 1a) Using this custom control in a XAML file that exists in the current project.
|
|
/// Add this XmlNamespace attribute to the root element of the markup file where it is
|
|
/// to be used:
|
|
///
|
|
/// xmlns:MyNamespace="clr-namespace:ENI2.Controls"
|
|
///
|
|
///
|
|
/// Step 1b) Using this custom control in a XAML file that exists in a different project.
|
|
/// Add this XmlNamespace attribute to the root element of the markup file where it is
|
|
/// to be used:
|
|
///
|
|
/// xmlns:MyNamespace="clr-namespace:ENI2.Controls;assembly=ENI2.Controls"
|
|
///
|
|
/// You will also need to add a project reference from the project where the XAML file lives
|
|
/// to this project and Rebuild to avoid compilation errors:
|
|
///
|
|
/// Right click on the target project in the Solution Explorer and
|
|
/// "Add Reference"->"Projects"->[Browse to and select this project]
|
|
///
|
|
///
|
|
/// Step 2)
|
|
/// Go ahead and use your control in the XAML file.
|
|
///
|
|
/// <MyNamespace:ClosableTabItem/>
|
|
///
|
|
/// </summary>
|
|
public class ClosableTabItem : TabItem
|
|
{
|
|
private Storyboard blinkTextStoryboard;
|
|
|
|
/*
|
|
*
|
|
static ClosableTabItem()
|
|
{
|
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ClosableTabItem), new FrameworkPropertyMetadata(typeof(ClosableTabItem)));
|
|
}
|
|
*/
|
|
private TextBlock textBlock;
|
|
|
|
public event CancelEventHandler TabClosing;
|
|
|
|
protected Storyboard BlinkTextStoryboard
|
|
{
|
|
get
|
|
{
|
|
if(blinkTextStoryboard == null)
|
|
{
|
|
this.blinkTextStoryboard = new Storyboard();
|
|
|
|
ColorAnimationUsingKeyFrames cauk = new ColorAnimationUsingKeyFrames();
|
|
cauk.AutoReverse = true;
|
|
cauk.KeyFrames.Add(new DiscreteColorKeyFrame(Colors.Black, KeyTime.FromTimeSpan(new TimeSpan(0,0,1))));
|
|
cauk.KeyFrames.Add(new DiscreteColorKeyFrame(Colors.Red, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 2))));
|
|
cauk.KeyFrames.Add(new DiscreteColorKeyFrame(Colors.White, KeyTime.FromTimeSpan(new TimeSpan(0, 0, 3))));
|
|
|
|
Storyboard.SetTarget(cauk, this.textBlock.Foreground);
|
|
Storyboard.SetTargetProperty(cauk, new PropertyPath(SolidColorBrush.ColorProperty));
|
|
|
|
this.blinkTextStoryboard.Children.Add(cauk);
|
|
|
|
}
|
|
return blinkTextStoryboard;
|
|
}
|
|
}
|
|
|
|
|
|
public bool IsHighlighted
|
|
{
|
|
private get { return false; }
|
|
set
|
|
{
|
|
|
|
if (value) this.textBlock.Foreground = Brushes.Red; //this.BlinkTextStoryboard.Begin(); // warum auch immer das nicht funktioniert
|
|
else this.textBlock.Foreground = Brushes.Black; //this.BlinkTextStoryboard.Stop();
|
|
}
|
|
}
|
|
|
|
public bool IsHighlightResponded
|
|
{
|
|
private get { return false; }
|
|
set
|
|
{
|
|
if (value) this.textBlock.Foreground = Brushes.Green;
|
|
else this.textBlock.Foreground = Brushes.Black;
|
|
}
|
|
}
|
|
|
|
public bool IsCancelled
|
|
{
|
|
private get { return false; }
|
|
set
|
|
{
|
|
if (value)
|
|
{
|
|
this.textBlock.Foreground = Brushes.Gray;
|
|
this.textBlock.Background = Brushes.LightGray;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetHeaderText(string headerText, bool lockedTab)
|
|
{
|
|
// Container for header controls
|
|
DockPanel dockPanel = new DockPanel();
|
|
dockPanel.Height = 22;
|
|
|
|
this.textBlock = new TextBlock { Text = headerText };
|
|
this.textBlock.Foreground = new SolidColorBrush(Colors.Black);
|
|
// this.textBlock.Background = lockedTab ? Brushes.LightGreen : Brushes.Orange; // sie wollen die bunten Panels doch nicht
|
|
this.textBlock.Margin = new Thickness(1);
|
|
this.textBlock.VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
dockPanel.Children.Add(this.textBlock);
|
|
|
|
// Close button to remove the tab
|
|
var closeButton = new Button();
|
|
closeButton.Content = "X";
|
|
closeButton.Margin = new Thickness(5, 0, 0, 0);
|
|
closeButton.Foreground = Brushes.Red;
|
|
closeButton.Height = 18;
|
|
closeButton.Width = 15;
|
|
closeButton.Opacity = 0.2;
|
|
closeButton.FontSize = 8;
|
|
closeButton.FontWeight = FontWeights.Bold;
|
|
closeButton.VerticalAlignment = VerticalAlignment.Center;
|
|
|
|
closeButton.MouseEnter += (sender, e) => {
|
|
DoubleAnimation animation = new DoubleAnimation(0.2, 1.0, new TimeSpan(0, 0, 0, 0, 500));
|
|
closeButton.BeginAnimation(Button.OpacityProperty, animation);
|
|
};
|
|
closeButton.MouseLeave += (sender, e) => {
|
|
DoubleAnimation animation = new DoubleAnimation(1.0, 0.2, new TimeSpan(0, 0, 0, 0, 500));
|
|
closeButton.BeginAnimation(Button.OpacityProperty, animation);
|
|
};
|
|
|
|
closeButton.Click +=
|
|
(sender, e) =>
|
|
{
|
|
bool abort = false;
|
|
if (TabClosing != null)
|
|
{
|
|
CancelEventArgs cancelEventArgs = new CancelEventArgs();
|
|
this.TabClosing(this, cancelEventArgs);
|
|
if (cancelEventArgs.Cancel) abort = true;
|
|
}
|
|
if (!abort)
|
|
{
|
|
var tabControl = Parent as TabControl;
|
|
tabControl.SelectedItem = null;
|
|
_ = Dispatcher.BeginInvoke(new Action(() => tabControl.Items.Remove(this)), DispatcherPriority.Background);
|
|
}
|
|
};
|
|
dockPanel.Children.Add(closeButton);
|
|
|
|
// Set the header
|
|
Header = dockPanel;
|
|
}
|
|
|
|
}
|
|
}
|