Skip to content

Instantly share code, notes, and snippets.

@nexpr
Created June 17, 2018 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nexpr/e41114123c0e06a013417000c48ecd2e to your computer and use it in GitHub Desktop.
Save nexpr/e41114123c0e06a013417000c48ecd2e to your computer and use it in GitHub Desktop.
Preview XAML

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;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment