WPF のデフォルト状態に MainWindow のコードを置いてビルド
example.xaml をドラッグ&ドロップでプレビューできる
ルートが Window だったりするとダメ
<DockPanel | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"> | |
<Label DockPanel.Dock="Top" Height="60" Background="aqua">1</Label> | |
<Label DockPanel.Dock="Left" Width="60" Background="yellowgreen">2</Label> | |
<Label DockPanel.Dock="Bottom" Height="60" Background="pink">3</Label> | |
<Label DockPanel.Dock="Right" Width="60" Background="thistle">4</Label> | |
<Label Background="orange">5</Label> | |
</DockPanel> |
<Window x:Class="XAMLView.MainWindow" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:local="clr-namespace:XAMLView" | |
mc:Ignorable="d" | |
Title="XAMLView" Height="600" Width="800" FontFamily="Meiryo"> | |
<Grid> | |
<TabControl x:Name="tabs"> | |
<TabControl.Resources> | |
<Style TargetType="TabItem"> | |
<Setter Property="Padding" Value="20 8"/> | |
</Style> | |
</TabControl.Resources> | |
<TabItem Header="NewTab" AllowDrop="True" MouseDown="TabItem_MouseDown"> | |
<Border Drop="Border_Drop" AllowDrop="True" Background="#FFF" /> | |
</TabItem> | |
<TabItem> | |
<TabItem.Template> | |
<ControlTemplate> | |
<Button Click="Button_Click" Content="+" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="10" Foreground="Gray"> | |
<Button.Template> | |
<ControlTemplate TargetType="Button"> | |
<Grid Margin="6 0"> | |
<Ellipse x:Name="round" Width="16" Height="16" Stroke="Gray"/> | |
<Line x:Name="crosslineH" X1="5" Y1="8" X2="11" Y2="8" Stroke="Gray" StrokeThickness="2"/> | |
<Line x:Name="crosslineV" X1="8" Y1="5" X2="8" Y2="11" Stroke="Gray" StrokeThickness="2"/> | |
</Grid> | |
<ControlTemplate.Triggers> | |
<Trigger Property="IsMouseOver" Value="True"> | |
<Setter Property="Fill" TargetName="round" Value="#FFF07C8B"></Setter> | |
<Setter Property="StrokeThickness" TargetName="round" Value="0"></Setter> | |
<Setter Property="Stroke" TargetName="crosslineH" Value="#f8f8f8"></Setter> | |
<Setter Property="Stroke" TargetName="crosslineV" Value="#f8f8f8"></Setter> | |
</Trigger> | |
</ControlTemplate.Triggers> | |
</ControlTemplate> | |
</Button.Template> | |
</Button> | |
</ControlTemplate> | |
</TabItem.Template> | |
<Grid Background="#666"> | |
<StackPanel Margin="30" MinWidth="100" MinHeight="100"> | |
<TextBlock Foreground="#FFEACC8C" FontSize="24" FontWeight="Bold" Margin="0 0 0 12">H E L P</TextBlock> | |
<TextBlock Foreground="#fff0f0" FontSize="16" LineHeight="32"> | |
+ ボタンを押してタブを開いてください。<LineBreak/> | |
.xaml ファイルをドロップするとプレビューされます。<LineBreak/> | |
ミドルクリックでタブを閉じます。 | |
</TextBlock> | |
</StackPanel> | |
</Grid> | |
</TabItem> | |
</TabControl> | |
</Grid> | |
</Window> |
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
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.Markup; | |
using System.Windows.Media; | |
using System.Windows.Media.Imaging; | |
using System.Windows.Navigation; | |
namespace XAMLView | |
{ | |
/// <summary> | |
/// MainWindow.xaml の相互作用ロジック | |
/// </summary> | |
public partial class MainWindow : Window | |
{ | |
public MainWindow() | |
{ | |
InitializeComponent(); | |
} | |
private void Button_Click(object sender, RoutedEventArgs e) | |
{ | |
this.createNewtab(); | |
} | |
private void TabItem_MouseDown(object sender, MouseButtonEventArgs e) | |
{ | |
if (e.ChangedButton == MouseButton.Middle && e.ButtonState == MouseButtonState.Pressed) | |
{ | |
var tab = sender as TabItem; | |
this.removeTab(tab); | |
} | |
} | |
private void Border_Drop(object sender, DragEventArgs e) | |
{ | |
if (e.Data.GetDataPresent(DataFormats.FileDrop)) | |
{ | |
var files = (string[])e.Data.GetData(DataFormats.FileDrop); | |
if (files.Length > 0) this.loadFiles(files); | |
} | |
} | |
private TabItem createNewtab() | |
{ | |
var border = new Border | |
{ | |
AllowDrop = true, | |
Background = Brushes.White, | |
}; | |
border.AddHandler(DropEvent, new DragEventHandler(this.Border_Drop)); | |
var tab = new TabItem | |
{ | |
Content = border, | |
Header = "NewTab", | |
}; | |
tab.AddHandler(MouseDownEvent, new MouseButtonEventHandler(this.TabItem_MouseDown)); | |
var new_index = this.tabs.Items.Count - 1; | |
this.tabs.Items.Insert(new_index, tab); | |
this.tabs.SelectedIndex = new_index; | |
return tab; | |
} | |
private void removeTab(TabItem tab) | |
{ | |
var index = this.tabs.Items.IndexOf(tab); | |
this.tabs.Items.Remove(tab); | |
this.tabs.SelectedIndex = Math.Max(0, index - 1); | |
} | |
private void loadFiles(string[] files) | |
{ | |
var is_first = true; | |
foreach (var filepath in files) | |
{ | |
if (!filepath.EndsWith(".xaml")) | |
{ | |
MessageBox.Show("XAML ファイルをドロップしてください。", filepath); | |
return; | |
} | |
try | |
{ | |
var element = this.readXAML(filepath); | |
if (element == null) | |
{ | |
throw new Exception("ルート要素は UIElement である必要があります。"); | |
} | |
if (is_first) | |
{ | |
// 1回目 | |
var tab = this.tabs.SelectedItem as TabItem; | |
this.showXAML(tab, element, filepath); | |
is_first = false; | |
} | |
else | |
{ | |
// 2回目以降 | |
var tab = this.createNewtab(); | |
this.showXAML(tab, element, filepath); | |
} | |
} | |
catch (Exception ex) | |
{ | |
MessageBox.Show(ex.Message, filepath); | |
} | |
} | |
} | |
private void showXAML(TabItem tab, UIElement xaml_root, string filepath) | |
{ | |
tab.Header = Path.GetFileName(filepath); | |
var frame = tab.Content as Border; | |
try | |
{ | |
frame.Child = xaml_root; | |
} | |
catch (Exception ex) | |
{ | |
frame.Child = new TextBlock { Text = "Error: \n" + ex.Message }; | |
} | |
} | |
private UIElement readXAML(string filepath) | |
{ | |
using (var reader = new StreamReader(filepath)) | |
{ | |
return XamlReader.Load(reader.BaseStream) as UIElement; | |
} | |
} | |
} | |
} |