项目结构调整

This commit is contained in:
艾竹
2023-04-16 20:11:40 +08:00
parent cbfbf96033
commit 81f91f3f35
2124 changed files with 218 additions and 5516 deletions

View File

@@ -0,0 +1,53 @@
using System;
using System.Windows.Input;
namespace DragablzDemo
{
/// <summary>
/// No WPF project is complete without it's own version of this.
/// </summary>
public class AnotherCommandImplementation : ICommand
{
private readonly Action<object> _execute;
private readonly Func<object, bool> _canExecute;
public AnotherCommandImplementation(Action<object> execute) : this(execute, null)
{
}
public AnotherCommandImplementation(Action<object> execute, Func<object, bool> canExecute)
{
if (execute == null) throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute ?? (x => true);
}
public bool CanExecute(object parameter)
{
return _canExecute(parameter);
}
public void Execute(object parameter)
{
_execute(parameter);
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
}
remove
{
CommandManager.RequerySuggested -= value;
}
}
public void Refresh()
{
CommandManager.InvalidateRequerySuggested();
}
}
}

View File

@@ -0,0 +1,45 @@
<Application x:Class="DragablzDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
>
<Application.Resources>
<Style TargetType="{x:Type dragablz:DragablzItem}" BasedOn="{StaticResource {x:Type dragablz:DragablzItem}}" x:Key="CustomDragablzItemStyle">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border BorderThickness="{TemplateBinding Border.BorderThickness}" Padding="{TemplateBinding Control.Padding}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Background="Cyan" x:Name="PART_DragableElement">
<TextBlock>DH</TextBlock>
</Border>
<Thumb Grid.Row="1" Width="30" Height="30" Background="Yellow" x:Name="PART_Thumb" />
<ContentPresenter Grid.Row="2" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<Style TargetType="{x:Type dragablz:TabablzControl}" x:Key="BasicExamplesTabStyle">
<Setter Property="Margin" Value="8 8 8 8" />
<Setter Property="HeaderPrefixContent" Value="☺" />
<Setter Property="HeaderSuffixContent" Value="☻" />
<Setter Property="HeaderSuffixContentTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock Text="☻" ToolTip="You can easily insert content here using HeaderSuffixContent" Margin="2 0 2 0"/>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>

View File

@@ -0,0 +1,11 @@
using System.Windows;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using Dragablz;
namespace DragablzDemo
{
public class BasicExampleInterTabClient : IInterTabClient
{
public INewTabHost<Window> GetNewHost(IInterTabClient interTabClient, object partition, TabablzControl source)
{
var view = new BasicExampleTemplateWindow();
var model = new BasicExampleTemplateModel(interTabClient, partition);
view.DataContext = model;
return new NewTabHost<Window>(view, view.TabablzControl);
}
public TabEmptiedResponse TabEmptiedHandler(TabablzControl tabControl, Window window)
{
return TabEmptiedResponse.CloseWindowOrLayoutBranch;
}
}
}

View File

@@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
using Dragablz;
using DragablzDemo.Annotations;
namespace DragablzDemo
{
public class BasicExampleMainModel : INotifyPropertyChanged
{
private readonly ObservableCollection<Person> _people = new ObservableCollection<Person>();
private readonly ObservableCollection<SimpleViewModel> _viewModels = new ObservableCollection<SimpleViewModel>();
private readonly ICommand _addNewPerson;
private readonly ICommand _addNewViewModel;
private readonly IInterTabClient _interTabClient;
private int _newPersonCount;
private int _newViewModelCount;
private SimpleViewModel _selectedViewModel;
private readonly PositionMonitor _basicColourMonitor;
private string _basicColourMonitorText = "awaiting...";
private readonly VerticalPositionMonitor _peopleMonitor;
private string _peopleMonitorText = "awaiting...";
public BasicExampleMainModel()
{
_basicColourMonitor = new PositionMonitor();
_basicColourMonitor.LocationChanged += (sender, args) => BasicColourMonitorText = args.Location.ToString();
_peopleMonitor = new VerticalPositionMonitor();
_peopleMonitor.OrderChanged += PeopleMonitorOnOrderChanged;
_people.Add(new Person {FirstName = "Albert", LastName = "Einstein"});
_people.Add(new Person { FirstName = "Neil", LastName = "Tyson" });
_people.Add(new Person { FirstName = "James", LastName = "Willock" }); //i move in esteemed circles ;)
_viewModels.Add(new SimpleViewModel { Name = "Alpha", SimpleContent = "This is the alpha content"});
_viewModels.Add(new SimpleViewModel { Name = "Beta", SimpleContent = "Beta content", IsSelected = true });
_viewModels.Add(new SimpleViewModel { Name = "Gamma", SimpleContent = "And here is the gamma content" });
SelectedViewModel = _viewModels[1];
_interTabClient = new BasicExampleInterTabClient();
_addNewPerson = new AnotherCommandImplementation(
x =>
{
_newPersonCount++;
_people.Add(new Person
{
FirstName = "Hello_" + _newPersonCount,
LastName = "World_" + _newPersonCount
});
});
_addNewViewModel = new AnotherCommandImplementation(
x =>
{
_newViewModelCount++;
_viewModels.Add(new SimpleViewModel()
{
Name = "New Tab " + _newViewModelCount,
SimpleContent = "New Tab Content " + _newViewModelCount
});
SelectedViewModel = _viewModels.Last();
});
}
public string BasicColourMonitorText
{
get { return _basicColourMonitorText; }
set
{
if (_basicColourMonitorText == value) return;
_basicColourMonitorText = value;
#if NET40
OnPropertyChanged("BasicColourMonitorText");
#endif
#if NET45
OnPropertyChanged();
#endif
}
}
public string PeopleMonitorText
{
get { return _peopleMonitorText; }
set
{
if (_peopleMonitorText == value) return;
_peopleMonitorText = value;
#if NET40
OnPropertyChanged("PeopleMonitorText");
#endif
#if NET45
OnPropertyChanged();
#endif
}
}
public ReadOnlyObservableCollection<Person> People
{
get { return new ReadOnlyObservableCollection<Person>(_people); }
}
public ICommand AddNewPerson
{
get { return _addNewPerson; }
}
public ObservableCollection<SimpleViewModel> ViewModels
{
get { return _viewModels; }
}
public SimpleViewModel SelectedViewModel
{
get { return _selectedViewModel; }
set
{
if (_selectedViewModel == value) return;
_selectedViewModel = value;
#if NET40
OnPropertyChanged("SelectedViewModel");
#endif
#if NET45
OnPropertyChanged();
#endif
}
}
public ICommand AddNewViewModel
{
get { return _addNewViewModel; }
}
public PositionMonitor BasicColourMonitor
{
get { return _basicColourMonitor; }
}
public PositionMonitor PeopleMonitor
{
get { return _peopleMonitor; }
}
public IInterTabClient BasicInterTabClient
{
get { return _interTabClient; }
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
#if NET40
protected virtual void OnPropertyChanged(string propertyName)
#else
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
#endif
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
private void PeopleMonitorOnOrderChanged(object sender, OrderChangedEventArgs orderChangedEventArgs)
{
PeopleMonitorText = orderChangedEventArgs.NewOrder.OfType<Person>()
.Aggregate("", (accumalate, person) => accumalate + person.LastName + ", ");
}
}
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}

View File

@@ -0,0 +1,131 @@
<Window x:Class="DragablzDemo.BasicExampleMainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
Title="Basic Example Defining Tab Content in XAML" Height="350" Width="600"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance dragablzDemo:BasicExampleMainModel, IsDesignTimeCreatable=False}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<dragablz:TabablzControl Style="{StaticResource BasicExamplesTabStyle}">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController />
</dragablz:TabablzControl.InterTabController>
<TabItem Header="Basic Examples" IsSelected="True">
<Grid Margin="8 8 8 8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0">Content Defined in XAML, organised horizontally</TextBlock>
<dragablz:DragablzItemsControl Grid.Column="0" Grid.Row="1" BorderThickness="1" BorderBrush="DarkBlue"
PositionMonitor="{Binding BasicColourMonitor}">
<dragablz:DragablzItemsControl.ItemsOrganiser>
<dragablz:HorizontalOrganiser />
</dragablz:DragablzItemsControl.ItemsOrganiser>
<TextBlock>Red</TextBlock>
<TextBlock>Green</TextBlock>
<TextBlock>Blue</TextBlock>
</dragablz:DragablzItemsControl>
<TextBlock Grid.Row="2" Grid.Column="0" TextWrapping="Wrap"
Text="{Binding BasicColourMonitorText, StringFormat='Your view model can monitor coordinates. Latest coords={0}'}" />
<TextBlock Grid.Row="0" Grid.Column="1" Margin="2 0">Content Bound From View Model, organised vertically</TextBlock>
<dragablz:DragablzItemsControl Grid.Column="1" Grid.Row="1" ItemsSource="{Binding People}" BorderThickness="1"
BorderBrush="DarkBlue"
ItemContainerStyle="{StaticResource CustomDragablzItemStyle}"
Margin="2 0"
PositionMonitor="{Binding PeopleMonitor}">
<dragablz:DragablzItemsControl.ItemsOrganiser>
<dragablz:VerticalOrganiser />
</dragablz:DragablzItemsControl.ItemsOrganiser>
<dragablz:DragablzItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type dragablzDemo:Person}">
<StackPanel>
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</dragablz:DragablzItemsControl.ItemTemplate>
</dragablz:DragablzItemsControl>
<Button Command="{Binding AddNewPerson}" Grid.Row="2" Grid.Column="1" Margin="2 0">Add New Bound Person</Button>
<TextBlock Grid.Row="3" Grid.Column="1" TextWrapping="Wrap"
Text="{Binding PeopleMonitorText, StringFormat='Your can monitor ordering: {0}'}" />
</Grid>
</TabItem>
<TabItem Header="Drag me!">
<TextBlock Margin="8 8 8 8">You can drag tabs around.</TextBlock>
</TabItem>
<TabItem Header="Basic bound tabs example">
<dragablz:TabablzControl Margin="8 8 8 8" ItemsSource="{Binding ViewModels}"
SelectedItem="{Binding SelectedViewModel}">
<dragablz:TabablzControl.HeaderSuffixContent>
<Button Command="{Binding AddNewViewModel}">+</Button>
</dragablz:TabablzControl.HeaderSuffixContent>
<TabControl.ContentTemplate>
<DataTemplate DataType="{x:Type dragablzDemo:SimpleViewModel}">
<TextBlock Text="{Binding SimpleContent}" />
</DataTemplate>
</TabControl.ContentTemplate>
<dragablz:TabablzControl.HeaderItemTemplate>
<DataTemplate DataType="{x:Type dragablzDemo:SimpleViewModel}">
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</dragablz:TabablzControl.HeaderItemTemplate>
<TabControl.ItemTemplate>
<DataTemplate DataType="{x:Type dragablzDemo:SimpleViewModel}">
<TextBlock Text="{Binding SimpleContent}" />
</DataTemplate>
</TabControl.ItemTemplate>
</dragablz:TabablzControl>
</TabItem>
<TabItem Header="Cool features">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<dragablz:Trapezoid Grid.Row="0" Margin="8 8 8 8">Trapezium/Trapezoid...pretty useful for tabs</dragablz:Trapezoid>
<dragablz:DragablzItem Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Top" Style="{StaticResource SizableFromBottomRightDragablzItemStyle}">
<TextBlock TextWrapping="Wrap" Margin="2 2 2 2">This is a dragablz item, which can be resized...pretty cool to let text arrange. Try dragging the bottom right of the border. A simple example style is used, but you can also create your own grips in content using DragablzItem.SizeGrip.</TextBlock>
</dragablz:DragablzItem>
<dragablz:DragablzItemsControl Grid.RowSpan="2" Grid.Row="0"
Style="{StaticResource FloatingDragablzItemsControlStyle}">
<dragablz:DragablzItem HorizontalAlignment="Left" VerticalAlignment="Top" Style="{StaticResource FloatingDragablzItemStyle}"
Background="White"
X="100" Y="150"
Width="150" Height="100">
<TextBlock TextWrapping="Wrap" Margin="2 2 2 2">This is a dragablz item, is floating aroung happily, you can size it on any part of the border, and drag it anywhere.</TextBlock>
</dragablz:DragablzItem>
<dragablz:HeaderedDragablzItem HeaderContent="Floating around"
Style="{StaticResource ToolDragablzItemStyle}"
X="110" Y="160"
Width="150" Height="100">
<TextBlock TextWrapping="Wrap" Margin="2 2 2 2">Ahh c'mon, this is basically just a tool window! I know you are asking where the close button is. Keep asking. Haven't got there yet. But this is WPF, so don't get lazy, just style it in for yourself!</TextBlock>
</dragablz:HeaderedDragablzItem>
</dragablz:DragablzItemsControl>
</Grid>
</TabItem>
</dragablz:TabablzControl>
</Window>

View File

@@ -0,0 +1,17 @@
using System.Windows;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for BasicExampleMainWindow.xaml
/// </summary>
public partial class BasicExampleMainWindow : Window
{
public BasicExampleMainWindow()
{
InitializeComponent();
DataContext = new BasicExampleMainModel();
}
}
}

View File

@@ -0,0 +1,27 @@
using Dragablz;
namespace DragablzDemo
{
public class BasicExampleTemplateModel
{
private readonly IInterTabClient _interTabClient;
private readonly object _partition;
public BasicExampleTemplateModel(IInterTabClient interTabClient, object partition)
{
_interTabClient = interTabClient;
_partition = partition;
}
public IInterTabClient InterTabClient
{
get { return _interTabClient; }
}
public object Partition
{
get { return _partition; }
}
}
}

View File

@@ -0,0 +1,19 @@
<Window x:Class="DragablzDemo.BasicExampleTemplateWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
Title="Basic Example Defining Tab Content in XAML" Height="300" Width="300"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance dragablzDemo:BasicExampleTemplateModel, IsDesignTimeCreatable=False}">
<dragablz:TabablzControl Margin="8 8 8 8"
x:Name="TabablzControl"
Style="{StaticResource BasicExamplesTabStyle}">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController InterTabClient="{Binding InterTabClient}" Partition="{Binding Partition}" />
</dragablz:TabablzControl.InterTabController>
</dragablz:TabablzControl>
</Window>

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for BasicExampleTemplateWindow.xaml
/// </summary>
public partial class BasicExampleTemplateWindow : Window
{
public BasicExampleTemplateWindow()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Interop;
using System.Windows.Media;
using Dragablz;
namespace DragablzDemo
{
public class Boot
{
[STAThread]
public static void Main(string[] args)
{
var app = new App {ShutdownMode = ShutdownMode.OnLastWindowClose};
app.InitializeComponent();
new QuickStartWindow().Show();
new BasicExampleMainWindow
{
DataContext = new BasicExampleMainModel()
}.Show();
var boundExampleModel = new BoundExampleModel(
new HeaderedItemViewModel
{
Header = "Fixed",
Content = "There is a dragablz:DragablzItemsControl.FixedItemCount of 1, so this header is fixed!"
},
new HeaderedItemViewModel {Header = "MDI Demo", Content = new MdiExample()},
new HeaderedItemViewModel
{
Header = "Layout Info",
Content = new LayoutManagementExample {DataContext = new LayoutManagementExampleViewModel()}
},
new HeaderedItemViewModel
{
Header = new CustomHeaderViewModel {Header = "Header"},
Content =
"This tab illustrates how an individual header can be customized, without having to change the DragablzItem tab header template."
},
new HeaderedItemViewModel {Header = "Tues", Content = "Tuesday's child is full of grace"} //,
//new HeaderedItemViewModel { Header = "Wed", Content = "Wednesday's child is full of woe" }//,
//new HeaderedItemViewModel { Header = "Thu", Content = "Thursday's child has far to go" },
//new HeaderedItemViewModel { Header = "Fri", Content = "Friday's child loving and giving" }//,
//new HeaderedItemViewModel { Header = "Sat", Content = "Saturday's child works hard for a living" },
//new HeaderedItemViewModel { Header = "Sun", Content = "Sunday's child is awkwardly not fitting into this demo" }
);
boundExampleModel.ToolItems.Add(
new HeaderedItemViewModel {Header = "January", Content = "Welcome to the January tool/float item."});
boundExampleModel.ToolItems.Add(
new HeaderedItemViewModel
{
Header = "July",
Content =
new Border
{
Background = Brushes.Yellow,
Child = new TextBlock {Text = "Welcome to the July tool/float item."},
HorizontalAlignment = HorizontalAlignment.Stretch
}
});
new BoundExampleWindow()
{
DataContext = boundExampleModel
}.Show();
app.Run();
}
}
}

View File

@@ -0,0 +1,24 @@
using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Threading;
using Dragablz;
namespace DragablzDemo
{
public class BoundExampleInterTabClient : IInterTabClient
{
public INewTabHost<Window> GetNewHost(IInterTabClient interTabClient, object partition, TabablzControl source)
{
var view = new BoundExampleWindow();
var model = new BoundExampleModel();
view.DataContext = model;
return new NewTabHost<Window>(view, view.InitialTabablzControl);
}
public TabEmptiedResponse TabEmptiedHandler(TabablzControl tabControl, Window window)
{
return TabEmptiedResponse.CloseWindowOrLayoutBranch;
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Security.RightsManagement;
using System.Text;
using System.Threading.Tasks;
using Dragablz;
using Dragablz.Dockablz;
using DragablzDemo.Annotations;
namespace DragablzDemo
{
public class BoundExampleModel
{
private readonly IInterTabClient _interTabClient = new BoundExampleInterTabClient();
private readonly ObservableCollection<HeaderedItemViewModel> _items;
private readonly ObservableCollection<HeaderedItemViewModel> _toolItems = new ObservableCollection<HeaderedItemViewModel>();
public BoundExampleModel()
{
_items = new ObservableCollection<HeaderedItemViewModel>();
}
public BoundExampleModel(params HeaderedItemViewModel[] items)
{
_items = new ObservableCollection<HeaderedItemViewModel>(items);
}
public ObservableCollection<HeaderedItemViewModel> Items
{
get { return _items; }
}
public static Guid TabPartition
{
get { return new Guid("2AE89D18-F236-4D20-9605-6C03319038E6"); }
}
public IInterTabClient InterTabClient
{
get { return _interTabClient; }
}
public ObservableCollection<HeaderedItemViewModel> ToolItems
{
get { return _toolItems; }
}
public ItemActionCallback ClosingTabItemHandler
{
get { return ClosingTabItemHandlerImpl; }
}
/// <summary>
/// Callback to handle tab closing.
/// </summary>
private static void ClosingTabItemHandlerImpl(ItemActionCallbackArgs<TabablzControl> args)
{
//in here you can dispose stuff or cancel the close
//here's your view model:
var viewModel = args.DragablzItem.DataContext as HeaderedItemViewModel;
Debug.Assert(viewModel != null);
//here's how you can cancel stuff:
//args.Cancel();
}
public ClosingFloatingItemCallback ClosingFloatingItemHandler
{
get { return ClosingFloatingItemHandlerImpl; }
}
/// <summary>
/// Callback to handle floating toolbar/MDI window closing.
/// </summary>
private static void ClosingFloatingItemHandlerImpl(ItemActionCallbackArgs<Layout> args)
{
//in here you can dispose stuff or cancel the close
//here's your view model:
var disposable = args.DragablzItem.DataContext as IDisposable;
if (disposable != null)
disposable.Dispose();
//here's how you can cancel stuff:
//args.Cancel();
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using Dragablz;
namespace DragablzDemo
{
public static class BoundExampleNewItem
{
public static Func<HeaderedItemViewModel> Factory
{
get
{
return
() =>
{
var dateTime = DateTime.Now;
return new HeaderedItemViewModel()
{
Header = dateTime.ToLongTimeString(),
Content = dateTime.ToString("R")
};
};
}
}
}
}

View File

@@ -0,0 +1,77 @@
<dragablz:DragablzWindow x:Class="DragablzDemo.BoundExampleWindow"
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"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
xmlns:dragablz="http://dragablz.net/winfx/xaml/dragablz"
xmlns:dockablz="http://dragablz.net/winfx/xaml/dockablz"
mc:Ignorable="d"
Title="Simple form of bound tabs" Height="300" Width="600"
d:DataContext="{d:DesignInstance dragablzDemo:BoundExampleModel, IsDesignTimeCreatable=False}">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Dragablz;component/Themes/Generic.xaml" />
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type dragablz:HeaderedItemViewModel}">
<ContentControl Content="{Binding Content}" Margin="4 4 4 4" FontSize="14" />
</DataTemplate>
<DataTemplate DataType="{x:Type dragablzDemo:CustomHeaderViewModel}">
<dragablzDemo:CustomHeader />
</DataTemplate>
<dragablz:InterTabController x:Key="InterTabController" x:Shared="False" InterTabClient="{Binding InterTabClient}" Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />
<dragablz:DragablzIcon Width="24" Height="24" Margin="0 -8 0 0"
x:Key="WindowIcon" x:Shared="False"
ToolTip="Added via the HeaderPrefixContent property"
/>
<Style TargetType="{x:Type dragablz:TabablzControl}" x:Key="TabablzControlStyle">
<Setter Property="NewItemFactory" Value="{x:Static dragablzDemo:BoundExampleNewItem.Factory}" />
<Setter Property="ItemsSource" Value="{Binding Items}" />
<Setter Property="ClosingItemCallback" Value="{Binding ClosingTabItemHandler}" />
<Setter Property="ShowDefaultAddButton" Value="True" />
<Setter Property="ShowDefaultCloseButton" Value="True" />
<Setter Property="AdjacentHeaderItemOffset" Value="-10" />
<Setter Property="ItemContainerStyle" Value="{StaticResource TrapezoidDragableTabItemStyle}" />
<Setter Property="HeaderMemberPath" Value="Header" />
<Setter Property="InterTabController" Value="{StaticResource InterTabController}" />
<Setter Property="Margin" Value="0 8 0 0" />
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(dockablz:Layout.IsTopLeftItem)}" Value="True">
<Setter Property="HeaderPrefixContent" Value="{StaticResource WindowIcon}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</Window.Resources>
<dockablz:Layout Partition="2AE89D18-F236-4D20-9605-6C03319038E6" Name="RootLayout"
FloatingItemsSource="{Binding ToolItems}"
FloatingItemHeaderMemberPath="Header"
IsFloatDropZoneEnabled="True"
ClosingFloatingItemCallback="{Binding ClosingFloatingItemHandler}"
FloatingItemsContainerMargin="0 2 0 0">
<!-- branch template lets dragablz create a new tab control after a window is split via docking -->
<dockablz:Layout.BranchTemplate>
<DataTemplate>
<dragablz:TabablzControl Style="{StaticResource TabablzControlStyle}">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController InterTabClient="{Binding InterTabClient}" Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />
</dragablz:TabablzControl.InterTabController>
</dragablz:TabablzControl>
</DataTemplate>
</dockablz:Layout.BranchTemplate>
<!-- a root, named tab control is needed, so when a tab is torn and a new window is created, the new target tab control can be identified -->
<dragablz:TabablzControl x:Name="InitialTabablzControl"
FixedHeaderCount="1"
Style="{StaticResource TabablzControlStyle}"
AddLocationHint="After">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController InterTabClient="{Binding InterTabClient}" Partition="2AE89D18-F236-4D20-9605-6C03319038E6" />
</dragablz:TabablzControl.InterTabController>
</dragablz:TabablzControl>
</dockablz:Layout>
</dragablz:DragablzWindow>

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for BoundExampleWindow.xaml
/// </summary>
public partial class BoundExampleWindow
{
public BoundExampleWindow()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,43 @@
<UserControl x:Class="DragablzDemo.CustomHeader"
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"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance dragablzDemo:CustomHeaderViewModel, IsDesignTimeCreatable=False}">
<!--
Illustrates how to add a custom header, without completely rewriting the DragablzItem header template.
Note that rewriting the DragablzItem header template is a perfectly valid thing to do, but this allows
customisation of existing templates.
-->
<UserControl.Resources>
<Style TargetType="{x:Type Thumb}" x:Key="InvisibleThumbStyle">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Background="{TemplateBinding Background}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</UserControl.Resources>
<StackPanel Orientation="Horizontal">
<Grid>
<TextBlock Text="{Binding Header}" />
<!-- you should provide your own Thumb, which will be used to monitor dragging -->
<Thumb Style="{DynamicResource InvisibleThumbStyle}"
dragablz:DragablzItem.IsCustomThumb="True" />
</Grid>
<CheckBox IsChecked="{Binding IsSelected}" ToolTip="Embed your own controls" />
<Button ToolTip="Manually add a close button"
Command="dragablz:TabablzControl.CloseItemCommand"
>X</Button>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for CustomHeader.xaml
/// </summary>
public partial class CustomHeader : UserControl
{
public CustomHeader()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using DragablzDemo.Annotations;
namespace DragablzDemo
{
public class CustomHeaderViewModel : INotifyPropertyChanged
{
private string _header;
private bool _isSelected;
public string Header
{
get { return _header; }
set
{
if (value == _header) return;
_header = value;
#if NET40
OnPropertyChanged("Header");
#else
OnPropertyChanged();
#endif
}
}
public bool IsSelected
{
get { return _isSelected; }
set
{
if (value.Equals(_isSelected)) return;
_isSelected = value;
#if NET40
OnPropertyChanged("IsSelected");
#else
OnPropertyChanged();
#endif
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
#if NET40
protected virtual void OnPropertyChanged(string propertyName)
#else
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
#endif
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net45</TargetFrameworks>
<UseWPF>true</UseWPF>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<StartupObject>DragablzDemo.Boot</StartupObject>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Dragablz\Dragablz.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,8 @@
namespace DragablzDemo
{
public class HeaderAndContentModel
{
public object Header { get; set; }
public object Content { get; set; }
}
}

View File

@@ -0,0 +1,49 @@
<UserControl x:Class="DragablzDemo.LayoutManagementExample"
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"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
d:DataContext="{d:DesignInstance dragablzDemo:LayoutManagementExampleViewModel, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<DataTemplate DataType="{x:Type dragablzDemo:TabablzControlProxy}">
<StackPanel Orientation="Horizontal">
<TextBlock>TabablzControl. Operations:</TextBlock>
<Button Command="{Binding SplitHorizontallyCommand}">Split Horizontally</Button>
<Button Command="{Binding SplitVerticallyCommand}">Split Vertically</Button>
<TextBlock>Ratio:</TextBlock>
<Slider Value="{Binding SplitRatio}" Width="160" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Command="{Binding QueryLayoutsCommand}">Query Layouts</Button>
<TreeView Grid.Row="1" ItemsSource="{Binding RootNodes}" x:Name="TreeView">
<TreeView.Resources>
<DataTemplate DataType="{x:Type dragablzDemo:TabablzControlProxy}">
<TextBlock>TabablzControl</TextBlock>
</DataTemplate>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type dragablzDemo:TreeNode}"
ItemsSource="{Binding Children}">
<ContentControl Content="{Binding Content}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<ContentControl Grid.Row="2" Content="{Binding ElementName=TreeView, Path=SelectedItem.Content}" />
</Grid>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for LayoutManagementExample.xaml
/// </summary>
public partial class LayoutManagementExample : UserControl
{
public LayoutManagementExample()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Dragablz;
using Dragablz.Dockablz;
namespace DragablzDemo
{
public class LayoutManagementExampleViewModel
{
private readonly ICommand _queryLayoutsCommand;
private readonly TreeNode _rootNode;
public LayoutManagementExampleViewModel()
{
_queryLayoutsCommand = new AnotherCommandImplementation(x => QueryLayouts());
_rootNode = new TreeNode
{
Content = "Application"
};
}
public ICommand QueryLayoutsCommand
{
get { return _queryLayoutsCommand; }
}
public IEnumerable<TreeNode> RootNodes
{
get { return new [] {_rootNode}; }
}
private void QueryLayouts()
{
_rootNode.Children.Clear();
foreach (var layout in Application.Current.Windows.OfType<BoundExampleWindow>().Select(w => w.RootLayout))
{
var layoutAccessor = layout.Query();
var layoutNode = new TreeNode
{
Content = "Layout"
};
_rootNode.Children.Add(layoutNode);
FloatingItemsVisitor(layoutNode, layoutAccessor);
layoutAccessor.Visit(layoutNode, BranchAccessorVisitor, TabablzControlVisitor);
}
}
private static void FloatingItemsVisitor(TreeNode layoutNode, LayoutAccessor layoutAccessor)
{
var floatingItems = layoutAccessor.FloatingItems.ToList();
var floatingItemsNode = new TreeNode {Content = "Floating Items " + floatingItems.Count};
foreach (var floatingItemNode in floatingItems.Select(floatingItem => new TreeNode
{
Content =
string.Format("Floating Item {0}, {1} : {2}, {3}", floatingItem.X, floatingItem.Y,
floatingItem.ActualWidth, floatingItem.ActualHeight)
}))
{
floatingItemsNode.Children.Add(floatingItemNode);
}
layoutNode.Children.Add(floatingItemsNode);
}
private static void TabablzControlVisitor(TreeNode treeNode, TabablzControl tabablzControl)
{
treeNode.Children.Add(new TreeNode { Content = new TabablzControlProxy(tabablzControl) });
}
private static void BranchAccessorVisitor(TreeNode treeNode, BranchAccessor branchAccessor)
{
var branchNode = new TreeNode {Content = "Branch " + branchAccessor.Branch.Orientation};
treeNode.Children.Add(branchNode);
var firstBranchNode = new TreeNode { Content = "Branch Item 1. Ratio=" + branchAccessor.Branch.GetFirstProportion() };
branchNode.Children.Add(firstBranchNode);
var secondBranchNode = new TreeNode { Content = "Branch Item 2. Ratio=" + (1 - branchAccessor.Branch.GetFirstProportion()) };
branchNode.Children.Add(secondBranchNode);
branchAccessor
.Visit(firstBranchNode, BranchItem.First, BranchAccessorVisitor, TabablzControlVisitor)
.Visit(secondBranchNode, BranchItem.Second, BranchAccessorVisitor, TabablzControlVisitor);
}
}
}

View File

@@ -0,0 +1,39 @@
<UserControl x:Class="DragablzDemo.MdiExample"
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"
xmlns:dockablz="clr-namespace:Dragablz.Dockablz;assembly=Dragablz"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:dragablzDemo="clr-namespace:DragablzDemo"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal">
<Button Command="{x:Static dockablz:Layout.TileFloatingItemsCommand}"
CommandTarget="{Binding ElementName=MdiLayout}">Tile Grid</Button>
<Button Command="{x:Static dockablz:Layout.TileFloatingItemsVerticallyCommand}"
CommandTarget="{Binding ElementName=MdiLayout}">Tile Horizontal</Button>
<Button Command="{x:Static dockablz:Layout.TileFloatingItemsHorizontallyCommand}"
CommandTarget="{Binding ElementName=MdiLayout}">Tile Vertical</Button>
</StackPanel>
<dockablz:Layout x:Name="MdiLayout"
FloatingItemHeaderMemberPath="Name"
FloatingItemDisplayMemberPath="SimpleContent">
<dockablz:Layout.FloatingItems>
<dragablzDemo:SimpleViewModel Name="One" SimpleContent="MDI Child One" />
<dragablzDemo:SimpleViewModel Name="Two" SimpleContent="MDI Child Two" />
<dragablzDemo:SimpleViewModel Name="Three" SimpleContent="MDI Child Three" />
<dragablzDemo:SimpleViewModel Name="Four" SimpleContent="MDI Child Four" />
<dragablzDemo:SimpleViewModel Name="Five" SimpleContent="MDI Child Five" />
<!--
<dragablzDemo:SimpleViewModel Name="Six" SimpleContent="MDI Child Six" />
<dragablzDemo:SimpleViewModel Name="Seven" SimpleContent="MDI Child Seven" />
<dragablzDemo:SimpleViewModel Name="Eight" SimpleContent="MDI Child Eight" />
<dragablzDemo:SimpleViewModel Name="Nine" SimpleContent="MDI Child Nine" />
<dragablzDemo:SimpleViewModel Name="Ten" SimpleContent="MDI Child Ten" />
-->
</dockablz:Layout.FloatingItems>
</dockablz:Layout>
</DockPanel>
</UserControl>

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for MdiExample.xaml
/// </summary>
public partial class MdiExample : UserControl
{
public MdiExample()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,614 @@
using System;
#pragma warning disable 1591
// ReSharper disable UnusedMember.Global
// ReSharper disable UnusedParameter.Local
// ReSharper disable MemberCanBePrivate.Global
// ReSharper disable UnusedAutoPropertyAccessor.Global
// ReSharper disable IntroduceOptionalParameters.Global
// ReSharper disable MemberCanBeProtected.Global
// ReSharper disable InconsistentNaming
namespace DragablzDemo.Annotations
{
/// <summary>
/// Indicates that the value of the marked element could be <c>null</c> sometimes,
/// so the check for <c>null</c> is necessary before its usage
/// </summary>
/// <example><code>
/// [CanBeNull] public object Test() { return null; }
/// public void UseTest() {
/// var p = Test();
/// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException'
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter |
AttributeTargets.Property | AttributeTargets.Delegate |
AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class CanBeNullAttribute : Attribute { }
/// <summary>
/// Indicates that the value of the marked element could never be <c>null</c>
/// </summary>
/// <example><code>
/// [NotNull] public object Foo() {
/// return null; // Warning: Possible 'null' assignment
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Method | AttributeTargets.Parameter |
AttributeTargets.Property | AttributeTargets.Delegate |
AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
public sealed class NotNullAttribute : Attribute { }
/// <summary>
/// Indicates that the marked method builds string by format pattern and (optional) arguments.
/// Parameter, which contains format string, should be given in constructor. The format string
/// should be in <see cref="string.Format(IFormatProvider,string,object[])"/>-like form
/// </summary>
/// <example><code>
/// [StringFormatMethod("message")]
/// public void ShowError(string message, params object[] args) { /* do something */ }
/// public void Foo() {
/// ShowError("Failed: {0}"); // Warning: Non-existing argument in format string
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Constructor | AttributeTargets.Method,
AllowMultiple = false, Inherited = true)]
public sealed class StringFormatMethodAttribute : Attribute
{
/// <param name="formatParameterName">
/// Specifies which parameter of an annotated method should be treated as format-string
/// </param>
public StringFormatMethodAttribute(string formatParameterName)
{
FormatParameterName = formatParameterName;
}
public string FormatParameterName { get; private set; }
}
/// <summary>
/// Indicates that the function argument should be string literal and match one
/// of the parameters of the caller function. For example, ReSharper annotates
/// the parameter of <see cref="System.ArgumentNullException"/>
/// </summary>
/// <example><code>
/// public void Foo(string param) {
/// if (param == null)
/// throw new ArgumentNullException("par"); // Warning: Cannot resolve symbol
/// }
/// </code></example>
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
public sealed class InvokerParameterNameAttribute : Attribute { }
/// <summary>
/// Indicates that the method is contained in a type that implements
/// <see cref="System.ComponentModel.INotifyPropertyChanged"/> interface
/// and this method is used to notify that some property value changed
/// </summary>
/// <remarks>
/// The method should be non-static and conform to one of the supported signatures:
/// <list>
/// <item><c>NotifyChanged(string)</c></item>
/// <item><c>NotifyChanged(params string[])</c></item>
/// <item><c>NotifyChanged{T}(Expression{Func{T}})</c></item>
/// <item><c>NotifyChanged{T,U}(Expression{Func{T,U}})</c></item>
/// <item><c>SetProperty{T}(ref T, T, string)</c></item>
/// </list>
/// </remarks>
/// <example><code>
/// public class Foo : INotifyPropertyChanged {
/// public event PropertyChangedEventHandler PropertyChanged;
/// [NotifyPropertyChangedInvocator]
/// protected virtual void NotifyChanged(string propertyName) { ... }
///
/// private string _name;
/// public string Name {
/// get { return _name; }
/// set { _name = value; NotifyChanged("LastName"); /* Warning */ }
/// }
/// }
/// </code>
/// Examples of generated notifications:
/// <list>
/// <item><c>NotifyChanged("Property")</c></item>
/// <item><c>NotifyChanged(() =&gt; Property)</c></item>
/// <item><c>NotifyChanged((VM x) =&gt; x.Property)</c></item>
/// <item><c>SetProperty(ref myField, value, "Property")</c></item>
/// </list>
/// </example>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class NotifyPropertyChangedInvocatorAttribute : Attribute
{
public NotifyPropertyChangedInvocatorAttribute() { }
public NotifyPropertyChangedInvocatorAttribute(string parameterName)
{
ParameterName = parameterName;
}
public string ParameterName { get; private set; }
}
/// <summary>
/// Describes dependency between method input and output
/// </summary>
/// <syntax>
/// <p>Function Definition Table syntax:</p>
/// <list>
/// <item>FDT ::= FDTRow [;FDTRow]*</item>
/// <item>FDTRow ::= Input =&gt; Output | Output &lt;= Input</item>
/// <item>Input ::= ParameterName: Value [, Input]*</item>
/// <item>Output ::= [ParameterName: Value]* {halt|stop|void|nothing|Value}</item>
/// <item>Value ::= true | false | null | notnull | canbenull</item>
/// </list>
/// If method has single input parameter, it's name could be omitted.<br/>
/// Using <c>halt</c> (or <c>void</c>/<c>nothing</c>, which is the same)
/// for method output means that the methos doesn't return normally.<br/>
/// <c>canbenull</c> annotation is only applicable for output parameters.<br/>
/// You can use multiple <c>[ContractAnnotation]</c> for each FDT row,
/// or use single attribute with rows separated by semicolon.<br/>
/// </syntax>
/// <examples><list>
/// <item><code>
/// [ContractAnnotation("=> halt")]
/// public void TerminationMethod()
/// </code></item>
/// <item><code>
/// [ContractAnnotation("halt &lt;= condition: false")]
/// public void Assert(bool condition, string text) // regular assertion method
/// </code></item>
/// <item><code>
/// [ContractAnnotation("s:null => true")]
/// public bool IsNullOrEmpty(string s) // string.IsNullOrEmpty()
/// </code></item>
/// <item><code>
/// // A method that returns null if the parameter is null, and not null if the parameter is not null
/// [ContractAnnotation("null => null; notnull => notnull")]
/// public object Transform(object data)
/// </code></item>
/// <item><code>
/// [ContractAnnotation("s:null=>false; =>true,result:notnull; =>false, result:null")]
/// public bool TryParse(string s, out Person result)
/// </code></item>
/// </list></examples>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public sealed class ContractAnnotationAttribute : Attribute
{
public ContractAnnotationAttribute([NotNull] string contract)
: this(contract, false) { }
public ContractAnnotationAttribute([NotNull] string contract, bool forceFullStates)
{
Contract = contract;
ForceFullStates = forceFullStates;
}
public string Contract { get; private set; }
public bool ForceFullStates { get; private set; }
}
/// <summary>
/// Indicates that marked element should be localized or not
/// </summary>
/// <example><code>
/// [LocalizationRequiredAttribute(true)]
/// public class Foo {
/// private string str = "my string"; // Warning: Localizable string
/// }
/// </code></example>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public sealed class LocalizationRequiredAttribute : Attribute
{
public LocalizationRequiredAttribute() : this(true) { }
public LocalizationRequiredAttribute(bool required)
{
Required = required;
}
public bool Required { get; private set; }
}
/// <summary>
/// Indicates that the value of the marked type (or its derivatives)
/// cannot be compared using '==' or '!=' operators and <c>Equals()</c>
/// should be used instead. However, using '==' or '!=' for comparison
/// with <c>null</c> is always permitted.
/// </summary>
/// <example><code>
/// [CannotApplyEqualityOperator]
/// class NoEquality { }
/// class UsesNoEquality {
/// public void Test() {
/// var ca1 = new NoEquality();
/// var ca2 = new NoEquality();
/// if (ca1 != null) { // OK
/// bool condition = ca1 == ca2; // Warning
/// }
/// }
/// }
/// </code></example>
[AttributeUsage(
AttributeTargets.Interface | AttributeTargets.Class |
AttributeTargets.Struct, AllowMultiple = false, Inherited = true)]
public sealed class CannotApplyEqualityOperatorAttribute : Attribute { }
/// <summary>
/// When applied to a target attribute, specifies a requirement for any type marked
/// with the target attribute to implement or inherit specific type or types.
/// </summary>
/// <example><code>
/// [BaseTypeRequired(typeof(IComponent)] // Specify requirement
/// public class ComponentAttribute : Attribute { }
/// [Component] // ComponentAttribute requires implementing IComponent interface
/// public class MyComponent : IComponent { }
/// </code></example>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
[BaseTypeRequired(typeof(Attribute))]
public sealed class BaseTypeRequiredAttribute : Attribute
{
public BaseTypeRequiredAttribute([NotNull] Type baseType)
{
BaseType = baseType;
}
[NotNull] public Type BaseType { get; private set; }
}
/// <summary>
/// Indicates that the marked symbol is used implicitly
/// (e.g. via reflection, in external library), so this symbol
/// will not be marked as unused (as well as by other usage inspections)
/// </summary>
[AttributeUsage(AttributeTargets.All, AllowMultiple = false, Inherited = true)]
public sealed class UsedImplicitlyAttribute : Attribute
{
public UsedImplicitlyAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
public UsedImplicitlyAttribute(ImplicitUseKindFlags useKindFlags)
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
public UsedImplicitlyAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags) { }
public UsedImplicitlyAttribute(
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
public ImplicitUseKindFlags UseKindFlags { get; private set; }
public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
/// <summary>
/// Should be used on attributes and causes ReSharper
/// to not mark symbols marked with such attributes as unused
/// (as well as by other usage inspections)
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public sealed class MeansImplicitUseAttribute : Attribute
{
public MeansImplicitUseAttribute()
: this(ImplicitUseKindFlags.Default, ImplicitUseTargetFlags.Default) { }
public MeansImplicitUseAttribute(ImplicitUseKindFlags useKindFlags)
: this(useKindFlags, ImplicitUseTargetFlags.Default) { }
public MeansImplicitUseAttribute(ImplicitUseTargetFlags targetFlags)
: this(ImplicitUseKindFlags.Default, targetFlags) { }
public MeansImplicitUseAttribute(
ImplicitUseKindFlags useKindFlags, ImplicitUseTargetFlags targetFlags)
{
UseKindFlags = useKindFlags;
TargetFlags = targetFlags;
}
[UsedImplicitly] public ImplicitUseKindFlags UseKindFlags { get; private set; }
[UsedImplicitly] public ImplicitUseTargetFlags TargetFlags { get; private set; }
}
[Flags]
public enum ImplicitUseKindFlags
{
Default = Access | Assign | InstantiatedWithFixedConstructorSignature,
/// <summary>Only entity marked with attribute considered used</summary>
Access = 1,
/// <summary>Indicates implicit assignment to a member</summary>
Assign = 2,
/// <summary>
/// Indicates implicit instantiation of a type with fixed constructor signature.
/// That means any unused constructor parameters won't be reported as such.
/// </summary>
InstantiatedWithFixedConstructorSignature = 4,
/// <summary>Indicates implicit instantiation of a type</summary>
InstantiatedNoFixedConstructorSignature = 8,
}
/// <summary>
/// Specify what is considered used implicitly
/// when marked with <see cref="MeansImplicitUseAttribute"/>
/// or <see cref="UsedImplicitlyAttribute"/>
/// </summary>
[Flags]
public enum ImplicitUseTargetFlags
{
Default = Itself,
Itself = 1,
/// <summary>Members of entity marked with attribute are considered used</summary>
Members = 2,
/// <summary>Entity marked with attribute and all its members considered used</summary>
WithMembers = Itself | Members
}
/// <summary>
/// This attribute is intended to mark publicly available API
/// which should not be removed and so is treated as used
/// </summary>
[MeansImplicitUse]
public sealed class PublicAPIAttribute : Attribute
{
public PublicAPIAttribute() { }
public PublicAPIAttribute([NotNull] string comment)
{
Comment = comment;
}
[NotNull] public string Comment { get; private set; }
}
/// <summary>
/// Tells code analysis engine if the parameter is completely handled
/// when the invoked method is on stack. If the parameter is a delegate,
/// indicates that delegate is executed while the method is executed.
/// If the parameter is an enumerable, indicates that it is enumerated
/// while the method is executed
/// </summary>
[AttributeUsage(AttributeTargets.Parameter, Inherited = true)]
public sealed class InstantHandleAttribute : Attribute { }
/// <summary>
/// Indicates that a method does not make any observable state changes.
/// The same as <c>System.Diagnostics.Contracts.PureAttribute</c>
/// </summary>
/// <example><code>
/// [Pure] private int Multiply(int x, int y) { return x * y; }
/// public void Foo() {
/// const int a = 2, b = 2;
/// Multiply(a, b); // Waring: Return value of pure method is not used
/// }
/// </code></example>
[AttributeUsage(AttributeTargets.Method, Inherited = true)]
public sealed class PureAttribute : Attribute { }
/// <summary>
/// Indicates that a parameter is a path to a file or a folder
/// within a web project. Path can be relative or absolute,
/// starting from web root (~)
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public class PathReferenceAttribute : Attribute
{
public PathReferenceAttribute() { }
public PathReferenceAttribute([PathReference] string basePath)
{
BasePath = basePath;
}
[NotNull] public string BasePath { get; private set; }
}
// ASP.NET MVC attributes
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcAreaMasterLocationFormatAttribute : Attribute
{
public AspMvcAreaMasterLocationFormatAttribute(string format) { }
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcAreaPartialViewLocationFormatAttribute : Attribute
{
public AspMvcAreaPartialViewLocationFormatAttribute(string format) { }
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcAreaViewLocationFormatAttribute : Attribute
{
public AspMvcAreaViewLocationFormatAttribute(string format) { }
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcMasterLocationFormatAttribute : Attribute
{
public AspMvcMasterLocationFormatAttribute(string format) { }
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcPartialViewLocationFormatAttribute : Attribute
{
public AspMvcPartialViewLocationFormatAttribute(string format) { }
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class AspMvcViewLocationFormatAttribute : Attribute
{
public AspMvcViewLocationFormatAttribute(string format) { }
}
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter
/// is an MVC action. If applied to a method, the MVC action name is calculated
/// implicitly from the context. Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcActionAttribute : Attribute
{
public AspMvcActionAttribute() { }
public AspMvcActionAttribute([NotNull] string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
[NotNull] public string AnonymousProperty { get; private set; }
}
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC area.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcAreaAttribute : PathReferenceAttribute
{
public AspMvcAreaAttribute() { }
public AspMvcAreaAttribute([NotNull] string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
[NotNull] public string AnonymousProperty { get; private set; }
}
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that
/// the parameter is an MVC controller. If applied to a method,
/// the MVC controller name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.ChildActionExtensions.RenderAction(HtmlHelper, String, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcControllerAttribute : Attribute
{
public AspMvcControllerAttribute() { }
public AspMvcControllerAttribute([NotNull] string anonymousProperty)
{
AnonymousProperty = anonymousProperty;
}
[NotNull] public string AnonymousProperty { get; private set; }
}
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC Master.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Controller.View(String, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcMasterAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC model type.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Controller.View(String, Object)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcModelTypeAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that
/// the parameter is an MVC partial view. If applied to a method,
/// the MVC partial view name is calculated implicitly from the context.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.RenderPartialExtensions.RenderPartial(HtmlHelper, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcPartialViewAttribute : PathReferenceAttribute { }
/// <summary>
/// ASP.NET MVC attribute. Allows disabling all inspections
/// for MVC views within a class or a method.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class AspMvcSupressViewErrorAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC display template.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.DisplayExtensions.DisplayForModel(HtmlHelper, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcDisplayTemplateAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC editor template.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Html.EditorExtensions.EditorForModel(HtmlHelper, String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcEditorTemplateAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. Indicates that a parameter is an MVC template.
/// Use this attribute for custom wrappers similar to
/// <c>System.ComponentModel.DataAnnotations.UIHintAttribute(System.String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter)]
public sealed class AspMvcTemplateAttribute : Attribute { }
/// <summary>
/// ASP.NET MVC attribute. If applied to a parameter, indicates that the parameter
/// is an MVC view. If applied to a method, the MVC view name is calculated implicitly
/// from the context. Use this attribute for custom wrappers similar to
/// <c>System.Web.Mvc.Controller.View(Object)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method)]
public sealed class AspMvcViewAttribute : PathReferenceAttribute { }
/// <summary>
/// ASP.NET MVC attribute. When applied to a parameter of an attribute,
/// indicates that this parameter is an MVC action name
/// </summary>
/// <example><code>
/// [ActionName("Foo")]
/// public ActionResult Login(string returnUrl) {
/// ViewBag.ReturnUrl = Url.Action("Foo"); // OK
/// return RedirectToAction("Bar"); // Error: Cannot resolve action
/// }
/// </code></example>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property)]
public sealed class AspMvcActionSelectorAttribute : Attribute { }
[AttributeUsage(
AttributeTargets.Parameter | AttributeTargets.Property |
AttributeTargets.Field, Inherited = true)]
public sealed class HtmlElementAttributesAttribute : Attribute
{
public HtmlElementAttributesAttribute() { }
public HtmlElementAttributesAttribute([NotNull] string name)
{
Name = name;
}
[NotNull] public string Name { get; private set; }
}
[AttributeUsage(
AttributeTargets.Parameter | AttributeTargets.Field |
AttributeTargets.Property, Inherited = true)]
public sealed class HtmlAttributeValueAttribute : Attribute
{
public HtmlAttributeValueAttribute([NotNull] string name)
{
Name = name;
}
[NotNull] public string Name { get; private set; }
}
// Razor attributes
/// <summary>
/// Razor attribute. Indicates that a parameter or a method is a Razor section.
/// Use this attribute for custom wrappers similar to
/// <c>System.Web.WebPages.WebPageBase.RenderSection(String)</c>
/// </summary>
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method, Inherited = true)]
public sealed class RazorSectionAttribute : Attribute { }
}

View File

@@ -0,0 +1,55 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("SaucyDemo")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("SaucyDemo")]
[assembly: AssemblyCopyright("Copyright © 2013")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DragablzDemo.net40.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DragablzDemo.net40.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace DragablzDemo.net40.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
}
}

View File

@@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@@ -0,0 +1,39 @@
<Window x:Class="DragablzDemo.QuickStartWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dragablz="clr-namespace:Dragablz;assembly=Dragablz"
xmlns:dockablz="clr-namespace:Dragablz.Dockablz;assembly=Dragablz"
xmlns:system="clr-namespace:System;assembly=mscorlib"
Title="Quick Start Window" Height="341" Width="617">
<Window.Resources>
<system:String x:Key="Partition">QuickStart</system:String>
</Window.Resources>
<dockablz:Layout Partition="{StaticResource Partition}">
<dragablz:TabablzControl Margin="8" ConsolidateOrphanedItems="True">
<dragablz:TabablzControl.InterTabController>
<dragablz:InterTabController Partition="{StaticResource Partition}" />
</dragablz:TabablzControl.InterTabController>
<TabItem Header="Tab No. 1" IsSelected="True">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Hello World</TextBlock>
</TabItem>
<TabItem Header="Tab No. 2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">We Have Tearable Tabs!</TextBlock>
</TabItem>
<TabItem>
<!-- with context menu -->
<TabItem.Header>
<Grid>
<Grid.ContextMenu>
<ContextMenu>
<!--we'll be in a popup, so give dragablz a hint as to what tab header content needs closing -->
<MenuItem Command="{x:Static dragablz:TabablzControl.CloseItemCommand}"/>
</ContextMenu>
</Grid.ContextMenu>
<TextBlock>Tab No. 3</TextBlock>
</Grid>
</TabItem.Header>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">I feel like an ice cold drink</TextBlock>
</TabItem>
</dragablz:TabablzControl>
</dockablz:Layout>
</Window>

View File

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace DragablzDemo
{
/// <summary>
/// Interaction logic for QuickStartWindow.xaml
/// </summary>
public partial class QuickStartWindow : Window
{
public QuickStartWindow()
{
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,44 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization.Formatters;
using DragablzDemo.Annotations;
namespace DragablzDemo
{
public class SimpleViewModel : INotifyPropertyChanged
{
private bool _isSelected;
public string Name { get; set; }
public object SimpleContent { get; set; }
public bool IsSelected
{
get { return _isSelected; }
set
{
if (_isSelected == value) return;
_isSelected = value;
#if NET40
OnPropertyChanged("IsSelected");
#else
OnPropertyChanged();
#endif
}
}
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
#if NET40
protected virtual void OnPropertyChanged(string propertyName)
#else
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
#endif
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,68 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows.Controls;
using System.Windows.Input;
using Dragablz;
using Dragablz.Dockablz;
namespace DragablzDemo
{
public class TabablzControlProxy : INotifyPropertyChanged
{
private readonly TabablzControl _tabablzControl;
private readonly ICommand _splitHorizontallyCommand;
private readonly ICommand _splitVerticallyCommand;
private double _splitRatio;
public TabablzControlProxy(TabablzControl tabablzControl)
{
_tabablzControl = tabablzControl;
_splitHorizontallyCommand = new AnotherCommandImplementation(_ => Branch(Orientation.Horizontal));
_splitVerticallyCommand = new AnotherCommandImplementation(_ => Branch(Orientation.Vertical));
SplitRatio = 5;
}
public ICommand SplitHorizontallyCommand
{
get { return _splitHorizontallyCommand; }
}
public ICommand SplitVerticallyCommand
{
get { return _splitVerticallyCommand; }
}
public double SplitRatio
{
get { return _splitRatio; }
set
{
_splitRatio = value;
OnPropertyChanged("SplitRatio");
}
}
private void Branch(Orientation orientation)
{
var branchResult = Layout.Branch(_tabablzControl, orientation, false, SplitRatio/10);
var newItem = new HeaderedItemViewModel
{
Header = "Code-Wise",
Content = "This item was added in via code, using Layout.Branch, and TabablzControl.AddToSource"
};
branchResult.TabablzControl.AddToSource(newItem);
branchResult.TabablzControl.SelectedItem = newItem;
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

@@ -0,0 +1,16 @@
using System.Collections.ObjectModel;
namespace DragablzDemo
{
public class TreeNode
{
private readonly ObservableCollection<TreeNode> _children = new ObservableCollection<TreeNode>();
public object Content { get; set; }
public ObservableCollection<TreeNode> Children
{
get { return _children; }
}
}
}