• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

XAMLで書けるインストーラを作るプロジェクト


コミットメタ情報

リビジョンb0d364a501b16611412e42ff37babb98f56f4060 (tree)
日時2011-06-04 11:49:50
作者azyobuzin <azyobuzin@user...>
コミッターazyobuzin

ログメッセージ

プロパティを増やしたりスタートページ作ったりした

変更サマリ

差分

--- a/XamlIn.Doc/XamlIn.Doc.shfbproj
+++ b/XamlIn.Doc/XamlIn.Doc.shfbproj
@@ -21,50 +21,61 @@
2121 <HelpTitle>XamlIn 説明書</HelpTitle>
2222 <DocumentationSources>
2323 <DocumentationSource sourceFile="..\XamlIn.Builder\XamlIn.Builder.csproj" xmlns="" />
24-<DocumentationSource sourceFile="..\XamlIn.Installer\XamlIn.Installer.csproj" xmlns="" /></DocumentationSources>
24+ <DocumentationSource sourceFile="..\XamlIn.Installer\XamlIn.Installer.csproj" xmlns="" />
25+ </DocumentationSources>
2526 <ComponentConfigurations>
2627 <ComponentConfig id="Cached Framework Comments Index Data" enabled="True" xmlns="">
2728 <component id="Cached Framework Comments Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
28-<index name="comments" value="/doc/members/member" key="@name" cache="100">
29+ <index name="comments" value="/doc/members/member" key="@name" cache="100">
2930 {@CachedFrameworkCommentList}
3031 {@CommentFileList}
3132 </index>
32-<copy name="comments" source="*" target="/document/comments" />
33-</component>
33+ <copy name="comments" source="*" target="/document/comments" />
34+ </component>
3435 </ComponentConfig>
35-<ComponentConfig id="Cached MSDN URL References" enabled="True" xmlns=""><component id="Cached MSDN URL References" type="SandcastleBuilder.Components.CachedResolveReferenceLinksComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll" locale="{@Locale}" linkTarget="{@SdkLinkTarget}">
36-<helpOutput format="HtmlHelp1">
37- <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
38- <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@HtmlSdkLinkType}" />
39- <targets files="reflection.xml" type="Local" />
40-</helpOutput>
41-<helpOutput format="MSHelp2">
42- <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
43- <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelp2SdkLinkType}" />
44- <targets files="reflection.xml" type="Index" />
45-</helpOutput>
46-<helpOutput format="MSHelpViewer">
47- <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
48- <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelpViewerSdkLinkType}" />
49- <targets files="reflection.xml" type="Id" />
50-</helpOutput>
51-<helpOutput format="Website">
52- <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
53- <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@WebsiteSdkLinkType}" />
54- <targets files="reflection.xml" type="Local" />
55-</helpOutput>
56-</component></ComponentConfig>
57-<ComponentConfig id="Cached Reflection Index Data" enabled="True" xmlns=""><component id="Cached Reflection Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
58-<index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
59- <cache base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" cacheFile="{@LocalDataFolder}Cache\Reflection.cache" />
60- <data files="reflection.xml" />
61-</index>
62-<copy name="reflection" source="*" target="/document/reference" />
63-</component></ComponentConfig></ComponentConfigurations>
36+ <ComponentConfig id="Cached MSDN URL References" enabled="True" xmlns="">
37+ <component id="Cached MSDN URL References" type="SandcastleBuilder.Components.CachedResolveReferenceLinksComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll" locale="{@Locale}" linkTarget="{@SdkLinkTarget}">
38+ <helpOutput format="HtmlHelp1">
39+ <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
40+ <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@HtmlSdkLinkType}" />
41+ <targets files="reflection.xml" type="Local" />
42+ </helpOutput>
43+ <helpOutput format="MSHelp2">
44+ <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
45+ <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelp2SdkLinkType}" />
46+ <targets files="reflection.xml" type="Index" />
47+ </helpOutput>
48+ <helpOutput format="MSHelpViewer">
49+ <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
50+ <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@MSHelpViewerSdkLinkType}" />
51+ <targets files="reflection.xml" type="Id" />
52+ </helpOutput>
53+ <helpOutput format="Website">
54+ <cache filename="{@LocalDataFolder}Cache\MsdnUrl.cache" />
55+ <targets base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" type="{@WebsiteSdkLinkType}" />
56+ <targets files="reflection.xml" type="Local" />
57+ </helpOutput>
58+ </component>
59+ </ComponentConfig>
60+ <ComponentConfig id="Cached Reflection Index Data" enabled="True" xmlns="">
61+ <component id="Cached Reflection Index Data" type="SandcastleBuilder.Components.CachedCopyFromIndexComponent" assembly="{@SHFBFolder}SandcastleBuilder.Components.dll">
62+ <index name="reflection" value="/reflection/apis/api" key="@id" cache="10">
63+ <cache base="{@SandcastlePath}Data\Reflection" recurse="true" files="*.xml" cacheFile="{@LocalDataFolder}Cache\Reflection.cache" />
64+ <data files="reflection.xml" />
65+ </index>
66+ <copy name="reflection" source="*" target="/document/reference" />
67+ </component>
68+ </ComponentConfig>
69+ </ComponentConfigurations>
6470 <NamespaceSummaries>
65- <NamespaceSummaryItem name="(global)" isDocumented="False" xmlns="" />
66-<NamespaceSummaryItem name="Azyobuzi.XamlIn.Builder" isDocumented="True" xmlns="">xinbuildに関係する名前空間</NamespaceSummaryItem>
67-<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer" isDocumented="True" xmlns="">XamlInのデータ構造とインストーラ本体</NamespaceSummaryItem></NamespaceSummaries>
71+ <NamespaceSummaryItem name="(global)" isDocumented="False" />
72+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Builder" isDocumented="True">xinbuildに関係する名前空間</NamespaceSummaryItem>
73+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer" isDocumented="True">XamlInの内部で使われているクラスなど</NamespaceSummaryItem>
74+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer.Models" isDocumented="True">公開されるデータ構造。XML名前空間は http://azyobuzinet.ohitashi.com/schemas/xamlin.html</NamespaceSummaryItem>
75+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer.ViewModels" isDocumented="True">ViewModelとか言っておきながらModelがないしすべてこの中で行おうとしてるのをなんとかしたいと思ってるクラスが入っている名前空間</NamespaceSummaryItem>
76+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer.Views" isDocumented="True">インストーラの画面などが入ってる名前空間</NamespaceSummaryItem>
77+<NamespaceSummaryItem name="XamlGeneratedNamespace" isDocumented="False" />
78+<NamespaceSummaryItem name="Azyobuzi.XamlIn.Installer.Views.DialogPages" isDocumented="True">デフォルトのページが入ってる名前空間。XML名前空間は http://azyobuzinet.ohitashi.com/schemas/xamlin.html</NamespaceSummaryItem></NamespaceSummaries>
6879 </PropertyGroup>
6980 <!-- There are no properties for these groups. AnyCPU needs to appear in
7081 order for Visual Studio to perform the build. The others are optional
--- a/XamlIn.Installer/App.xaml
+++ b/XamlIn.Installer/App.xaml
@@ -1,7 +1,7 @@
11 <Application x:Class="Azyobuzi.XamlIn.Installer.App"
22 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
33 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4- StartupUri="Views\MainWindow.xaml">
4+ Startup="Application_Startup">
55 <Application.Resources>
66
77 </Application.Resources>
--- a/XamlIn.Installer/App.xaml.cs
+++ b/XamlIn.Installer/App.xaml.cs
@@ -12,5 +12,17 @@ namespace Azyobuzi.XamlIn.Installer
1212 /// </summary>
1313 public partial class App : Application
1414 {
15+ private void Application_Startup(object sender, StartupEventArgs e)
16+ {
17+ var w = new Views.MainWindow();
18+#if DEBUG
19+ w.DataContext = new ViewModels.MainWindowViewModel(
20+ new Models.XamlIn()
21+ {
22+ ProductName = "Hoge"
23+ });
24+#endif
25+ w.Show();
26+ }
1527 }
1628 }
--- /dev/null
+++ b/XamlIn.Installer/DelegateCommand.cs
@@ -0,0 +1,120 @@
1+using System;
2+using System.Windows.Input;
3+
4+namespace Azyobuzi.XamlIn.Installer
5+{
6+ //http://d.hatena.ne.jp/okazuki/20100223/1266897125
7+ #region No parameter DelegateCommand
8+ internal sealed class DelegateCommand : ICommand
9+ {
10+ private Action _execute;
11+ private Func<bool> _canExecute;
12+
13+ public DelegateCommand(Action execute)
14+ : this(execute, () => true)
15+ {
16+ }
17+ public DelegateCommand(Action execute, Func<bool> canExecute)
18+ {
19+ _execute = execute;
20+ _canExecute = canExecute;
21+ }
22+
23+ public bool CanExecute()
24+ {
25+ return _canExecute();
26+ }
27+
28+ public void Execute()
29+ {
30+ _execute();
31+ }
32+
33+ public event EventHandler CanExecuteChanged
34+ {
35+ add { CommandManager.RequerySuggested += value; }
36+ remove { CommandManager.RequerySuggested -= value; }
37+ }
38+
39+ #region ICommand
40+ bool ICommand.CanExecute(object parameter)
41+ {
42+ return CanExecute();
43+ }
44+ void ICommand.Execute(object parameter)
45+ {
46+ Execute();
47+ }
48+ #endregion
49+ }
50+ #endregion
51+
52+ #region Parameter DelegateCommand
53+ internal sealed class DelegateCommand<T> : ICommand
54+ {
55+ private Action<T> _execute;
56+ private Func<T, bool> _canExecute;
57+
58+ private static readonly bool IS_VALUE_TYPE;
59+
60+ static DelegateCommand()
61+ {
62+ IS_VALUE_TYPE = typeof(T).IsValueType;
63+ }
64+
65+
66+ public DelegateCommand(Action<T> execute)
67+ : this(execute, o => true)
68+ {
69+ }
70+
71+ public DelegateCommand(Action<T> execute, Func<T, bool> canExecute)
72+ {
73+ _execute = execute;
74+ _canExecute = canExecute;
75+ }
76+
77+ public bool CanExecute(T parameter)
78+ {
79+ return _canExecute(parameter);
80+ }
81+
82+ public void Execute(T parameter)
83+ {
84+ _execute(parameter);
85+ }
86+
87+ public event EventHandler CanExecuteChanged
88+ {
89+ add { CommandManager.RequerySuggested += value; }
90+ remove { CommandManager.RequerySuggested -= value; }
91+ }
92+ #region ICommand
93+ bool ICommand.CanExecute(object parameter)
94+ {
95+ return CanExecute(Cast(parameter));
96+ }
97+
98+ void ICommand.Execute(object parameter)
99+ {
100+ Execute(Cast(parameter));
101+ }
102+ #endregion
103+
104+ /// <summary>
105+ /// convert parameter value
106+ /// </summary>
107+ /// <param name="parameter"></param>
108+ /// <returns></returns>
109+ private T Cast(object parameter)
110+ {
111+ if (parameter == null && IS_VALUE_TYPE)
112+ {
113+ return default(T);
114+ }
115+ return (T)parameter;
116+ }
117+ }
118+
119+ #endregion
120+}
Binary files /dev/null and b/XamlIn.Installer/Images/MultimediaModern05.bmp differ
--- /dev/null
+++ b/XamlIn.Installer/Models/DialogPageCollection.cs
@@ -0,0 +1,69 @@
1+using System.Windows;
2+using System.Windows.Controls;
3+
4+namespace Azyobuzi.XamlIn.Installer.Models
5+{
6+ /// <summary>
7+ /// ダイアログのページとなる<see cref="Control"/>のコレクション
8+ /// </summary>
9+ public class DialogPageCollection : FreezableCollection<Control>
10+ {
11+
12+ /// <summary>
13+ /// <see cref="IdProperty"/>の値を取得します。
14+ /// </summary>
15+ /// <param name="obj">読み取り元</param>
16+ /// <returns><see cref="IdProperty"/>の値</returns>
17+ public static string GetId(DependencyObject obj)
18+ {
19+ return (string)obj.GetValue(IdProperty);
20+ }
21+
22+ /// <summary>
23+ /// <see cref="IdProperty"/>に値を設定します。
24+ /// </summary>
25+ /// <param name="obj">書き込み先</param>
26+ /// <param name="value">設定する値</param>
27+ public static void SetId(DependencyObject obj, string value)
28+ {
29+ obj.SetValue(IdProperty, value);
30+ }
31+
32+ // Using a DependencyProperty as the backing store for Id. This enables animation, styling, binding, etc...
33+ /// <summary>
34+ /// ダイアログページの識別子を格納する添付プロパティの識別子
35+ /// </summary>
36+ public static readonly DependencyProperty IdProperty =
37+ DependencyProperty.RegisterAttached("Id", typeof(string), typeof(DialogPageCollection), new UIPropertyMetadata(null));
38+
39+
40+ /// <summary>
41+ /// <see cref="IndexProperty"/>の値を取得します。
42+ /// </summary>
43+ /// <param name="obj">読み取り元</param>
44+ /// <returns><see cref="IdProperty"/>の値</returns>
45+ public static int? GetIndex(DependencyObject obj)
46+ {
47+ return (int?)obj.GetValue(IndexProperty);
48+ }
49+
50+ /// <summary>
51+ /// <see cref="IndexProperty"/>に値を設定します。
52+ /// </summary>
53+ /// <param name="obj">書き込み先</param>
54+ /// <param name="value">設定する値</param>
55+ public static void SetIndex(DependencyObject obj, int? value)
56+ {
57+ obj.SetValue(IndexProperty, value);
58+ }
59+
60+ // Using a DependencyProperty as the backing store for Index. This enables animation, styling, binding, etc...
61+ /// <summary>
62+ /// ダイアログページの順番を格納する添付プロパティの識別子
63+ /// </summary>
64+ public static readonly DependencyProperty IndexProperty =
65+ DependencyProperty.RegisterAttached("Index", typeof(int?), typeof(DialogPageCollection), new UIPropertyMetadata(null));
66+
67+
68+ }
69+}
--- a/XamlIn.Installer/Models/File.cs
+++ b/XamlIn.Installer/Models/File.cs
@@ -25,14 +25,8 @@ namespace Azyobuzi.XamlIn.Installer.Models
2525 DependencyProperty.Register("Source", typeof(string), typeof(File));
2626
2727 /// <summary>
28- /// ファイル名。このこの名前を使ってパッケージにアクセスできます。
28+ /// ファイルの識別子。被らなければなんでもOK
2929 /// </summary>
30- public string Name
31- {
32- get
33- {
34- return Path.GetFileName(this.Source);
35- }
36- }
30+ public string Id { set; get; }
3731 }
3832 }
--- a/XamlIn.Installer/Models/FileCollection.cs
+++ b/XamlIn.Installer/Models/FileCollection.cs
@@ -1,11 +1,11 @@
1-using System.Collections.ObjectModel;
1+using System.Windows;
22
33 namespace Azyobuzi.XamlIn.Installer.Models
44 {
55 /// <summary>
66 /// <see cref="File"/>のコレクション
77 /// </summary>
8- public class FileCollection : Collection<File>
8+ public class FileCollection : FreezableCollection<File>
99 {
1010 }
1111 }
--- /dev/null
+++ b/XamlIn.Installer/Models/IInstallAction.cs
@@ -0,0 +1,16 @@
1+using Azyobuzi.XamlIn.Installer.ViewModels;
2+
3+namespace Azyobuzi.XamlIn.Installer.Models
4+{
5+ /// <summary>
6+ /// インストール時に実行されるアクション
7+ /// </summary>
8+ public interface IInstallAction
9+ {
10+ /// <summary>
11+ /// アクションを実行します。
12+ /// </summary>
13+ /// <param name="vm">ViewModel</param>
14+ void InvokeInstallAction(MainWindowViewModel vm);
15+ }
16+}
--- /dev/null
+++ b/XamlIn.Installer/Models/IUninstallAction.cs
@@ -0,0 +1,16 @@
1+using Azyobuzi.XamlIn.Installer.ViewModels;
2+
3+namespace Azyobuzi.XamlIn.Installer.Models
4+{
5+ /// <summary>
6+ /// アンインストール時に実行されるアクション
7+ /// </summary>
8+ public interface IUninstallAction
9+ {
10+ /// <summary>
11+ /// アクションを実行します。
12+ /// </summary>
13+ /// <param name="vm">ViewModel</param>
14+ void InvokeUninstallAction(MainWindowViewModel vm);
15+ }
16+}
--- a/XamlIn.Installer/Models/XamlIn.cs
+++ b/XamlIn.Installer/Models/XamlIn.cs
@@ -20,7 +20,7 @@ namespace Azyobuzi.XamlIn.Installer.Models
2020 }
2121
2222 /// <summary>
23- /// ソースファイルのコレクション
23+ /// ソースファイルのコレクション。複数ファイルで設定可能。
2424 /// </summary>
2525 public FileCollection Files { set; get; }
2626
@@ -33,5 +33,26 @@ namespace Azyobuzi.XamlIn.Installer.Models
3333 /// インストーラのウィンドウの高さ。初期値は380。
3434 /// </summary>
3535 public double WindowHeight { set; get; }
36+
37+ /// <summary>
38+ /// 製品名。アンインストール情報として使用されます。
39+ /// </summary>
40+ public string ProductName { set; get; }
41+
42+ /// <summary>
43+ /// 識別子。アンインストール情報を格納するレジストリのキーとして使用されます。
44+ /// 他の製品と被らないようにしてください。
45+ /// </summary>
46+ public string Id { set; get; }
47+
48+ /// <summary>
49+ /// 製品のバージョン
50+ /// </summary>
51+ public Version ProductVersion { set; get; }
52+
53+ /// <summary>
54+ /// ダイアログのリスト。複数ファイルで設定可能。
55+ /// </summary>
56+ public DialogPageCollection DialogPages { set; get; }
3657 }
3758 }
--- a/XamlIn.Installer/NotifyObject.cs
+++ b/XamlIn.Installer/NotifyObject.cs
@@ -1,12 +1,12 @@
11 using System;
2-using System.Collections.Generic;
3-using System.Linq;
4-using System.Text;
52 using System.ComponentModel;
63 using System.Linq.Expressions;
74
85 namespace Azyobuzi.XamlIn.Installer
96 {
7+ /// <summary>
8+ /// <see cref="INotifyPropertyChanged"/>を実装したオブジェクト。内部で使用されます。
9+ /// </summary>
1010 public abstract class NotifyObject : INotifyPropertyChanged
1111 {
1212 /// <summary>
--- a/XamlIn.Installer/Properties/AssemblyInfo.cs
+++ b/XamlIn.Installer/Properties/AssemblyInfo.cs
@@ -53,4 +53,6 @@ using System.Windows.Markup;
5353 [assembly: AssemblyVersion("1.0.0.0")]
5454 [assembly: AssemblyFileVersion("1.0.0.0")]
5555
56-[assembly: XmlnsDefinition("http://azyobuzinet.ohitashi.com/schemas/xamlin.html", "Azyobuzi.XamlIn.Installer.Models")]
\ No newline at end of file
56+[assembly: XmlnsDefinition("http://azyobuzinet.ohitashi.com/schemas/xamlin.html", "Azyobuzi.XamlIn.Installer.Models")]
57+[assembly: XmlnsDefinition("http://azyobuzinet.ohitashi.com/schemas/xamlin.html", "Azyobuzi.XamlIn.Installer.Views.DialogPages")]
58+[assembly: XmlnsPrefix("http://azyobuzinet.ohitashi.com/schemas/xamlin.html", "xin")]
\ No newline at end of file
--- a/XamlIn.Installer/ViewModels/MainWindowViewModel.cs
+++ b/XamlIn.Installer/ViewModels/MainWindowViewModel.cs
@@ -2,13 +2,65 @@
22 using System.Collections.Generic;
33 using System.Linq;
44 using System.Text;
5+using System.Windows.Input;
6+using Azyobuzi.XamlIn.Installer.Models;
57
68 namespace Azyobuzi.XamlIn.Installer.ViewModels
79 {
810 /// <summary>
9- /// <see cref="MainWindow"/>のViewModel。のはずなのにコントロールもってたりModelの役もしたり。
11+ /// <see cref="Views.MainWindow"/>のViewModel。のはずなのにコントロールもってたりModelの役もしたり。
1012 /// </summary>
11- public class MainWindowViewModel : NotifyObject
13+ public class MainWindowViewModel : ViewModelBase
1214 {
15+ /// <summary>
16+ /// コンストラクタ
17+ /// </summary>
18+ /// <param name="project">インストーラの情報を格納している<see cref="Models.XamlIn"/></param>
19+ public MainWindowViewModel(Models.XamlIn project)
20+ {
21+ this.Project = project;
22+ }
23+
24+ /// <summary>
25+ /// インストーラの情報
26+ /// </summary>
27+ public Models.XamlIn Project { private set; get; }
28+
29+ private bool isInstalling = false;
30+ /// <summary>
31+ /// インストール作業中かどうか
32+ /// </summary>
33+ public bool IsInstalling
34+ {
35+ set
36+ {
37+ if (isInstalling != value)
38+ {
39+ isInstalling = value;
40+ RaisePropertyChanged(() => this.IsInstalling);
41+ }
42+ }
43+ get
44+ {
45+ return isInstalling;
46+ }
47+ }
48+
49+ private ICommand cancelCommand;
50+ /// <summary>
51+ /// インストーラを終了させるコマンド
52+ /// </summary>
53+ public ICommand CancelCommand
54+ {
55+ get
56+ {
57+ if (this.cancelCommand == null)
58+ this.cancelCommand = new DelegateCommand(
59+ () => this.RaiseMessage(new RaisedMessageEventArgs { MessageKey = "Cancel" }),
60+ () => !this.IsInstalling
61+ );
62+ return this.cancelCommand;
63+ }
64+ }
1365 }
1466 }
--- /dev/null
+++ b/XamlIn.Installer/ViewModels/ViewModelBase.cs
@@ -0,0 +1,41 @@
1+using System;
2+
3+namespace Azyobuzi.XamlIn.Installer.ViewModels
4+{
5+ /// <summary>
6+ /// 内部で使用するViewModelのベース
7+ /// </summary>
8+ public abstract class ViewModelBase : NotifyObject
9+ {
10+ /// <summary>
11+ /// メッセージが送信されたときに発生します。
12+ /// </summary>
13+ public event EventHandler<RaisedMessageEventArgs> RaisedMessage;
14+
15+ /// <summary>
16+ /// メッセージを送信します。
17+ /// </summary>
18+ /// <param name="e"><see cref="RaisedMessageEventArgs"/>のインスタンス</param>
19+ protected void RaiseMessage(RaisedMessageEventArgs e)
20+ {
21+ if (RaisedMessage != null)
22+ RaisedMessage(this, e);
23+ }
24+ }
25+
26+ /// <summary>
27+ /// 内部で使用するメッセージの内容
28+ /// </summary>
29+ public class RaisedMessageEventArgs : EventArgs
30+ {
31+ /// <summary>
32+ /// メッセージの識別子
33+ /// </summary>
34+ public string MessageKey { set; get; }
35+
36+ /// <summary>
37+ /// メッセージとして渡すオブジェクト
38+ /// </summary>
39+ public object Object { set; get; }
40+ }
41+}
--- /dev/null
+++ b/XamlIn.Installer/Views/DialogPages/StartPage.xaml
@@ -0,0 +1,64 @@
1+<UserControl x:Class="Azyobuzi.XamlIn.Installer.Views.DialogPages.StartPage"
2+ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+ mc:Ignorable="d"
7+ d:DesignHeight="353" d:DesignWidth="494">
8+ <Grid>
9+ <Grid.Resources>
10+ <Style TargetType="TextBlock">
11+ <Setter Property="TextWrapping" Value="Wrap"/>
12+ </Style>
13+ </Grid.Resources>
14+ <Grid.ColumnDefinitions>
15+ <ColumnDefinition Width="auto"/>
16+ <ColumnDefinition/>
17+ </Grid.ColumnDefinitions>
18+ <Grid.RowDefinitions>
19+ <RowDefinition/>
20+ <RowDefinition Height="auto"/>
21+ </Grid.RowDefinitions>
22+
23+ <Image Grid.Column="0" Grid.Row="0" Source="/Setup;component/Images/MultimediaModern05.bmp" Stretch="UniformToFill" />
24+
25+ <StackPanel Grid.Column="1" Grid.Row="0" Margin="20">
26+ <TextBlock FontSize="14"
27+ Margin="0,15,0,20"
28+ Text="{Binding Path=Project.ProductName, StringFormat={}{0}のセットアップ}"/>
29+ <TextBlock>
30+ <TextBlock.Text>
31+ インストールを開始する前にすべてのアプリケーションを終了することをお勧めします。続行する場合は[次へ]をクリックしてください。
32+ </TextBlock.Text>
33+ </TextBlock>
34+ </StackPanel>
35+
36+ <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1"
37+ Background="{StaticResource {x:Static SystemColors.ControlBrushKey}}">
38+ <Grid.Resources>
39+ <Style TargetType="Button">
40+ <Setter Property="Width" Value="75"/>
41+ <Setter Property="Margin" Value="0,10,0,10"/>
42+ </Style>
43+ </Grid.Resources>
44+ <Grid.ColumnDefinitions>
45+ <ColumnDefinition/>
46+ <ColumnDefinition Width="auto"/>
47+ <ColumnDefinition Width="auto"/>
48+ <ColumnDefinition Width="auto"/>
49+ </Grid.ColumnDefinitions>
50+ <Grid.RowDefinitions>
51+ <RowDefinition Height="auto"/>
52+ <RowDefinition Height="auto"/>
53+ </Grid.RowDefinitions>
54+
55+ <Border Grid.Column="0" Grid.ColumnSpan="4" Grid.Row="0" BorderBrush="Silver" BorderThickness="0,1,0,0"/>
56+
57+ <Button Grid.Column="1" Grid.Row="1" Content="戻る(_B)"/>
58+ <Button Grid.Column="2" Grid.Row="2" Content="次へ(_N)"/>
59+ <Button Grid.Column="3" Grid.Row="3" Content="キャンセル"
60+ Margin="15,10,10,10"
61+ Command="{Binding CancelCommand}"/>
62+ </Grid>
63+ </Grid>
64+</UserControl>
--- /dev/null
+++ b/XamlIn.Installer/Views/DialogPages/StartPage.xaml.cs
@@ -0,0 +1,30 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Linq;
4+using System.Text;
5+using System.Windows;
6+using System.Windows.Controls;
7+using System.Windows.Data;
8+using System.Windows.Documents;
9+using System.Windows.Input;
10+using System.Windows.Media;
11+using System.Windows.Media.Imaging;
12+using System.Windows.Navigation;
13+using System.Windows.Shapes;
14+
15+namespace Azyobuzi.XamlIn.Installer.Views.DialogPages
16+{
17+ /// <summary>
18+ /// デフォルトのスタートページ
19+ /// </summary>
20+ public partial class StartPage : UserControl
21+ {
22+ /// <summary>
23+ /// コンストラクタ
24+ /// </summary>
25+ public StartPage()
26+ {
27+ InitializeComponent();
28+ }
29+ }
30+}
--- a/XamlIn.Installer/Views/MainWindow.xaml
+++ b/XamlIn.Installer/Views/MainWindow.xaml
@@ -2,11 +2,13 @@
22 Name="mainWindow"
33 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
44 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5- Title=""
5+ xmlns:p="clr-namespace:Azyobuzi.XamlIn.Installer.Views.DialogPages"
6+ Title="{Binding Path=Project.ProductName, StringFormat={}{0} Installation}"
67 Icon="/Setup;component/install.ico"
78 Width="500"
89 Height="380"
10+ Loaded="mainWindow_Loaded"
911 WindowStartupLocation="CenterScreen"
1012 ResizeMode="CanMinimize">
11-
13+ <p:StartPage/>
1214 </Window>
--- a/XamlIn.Installer/Views/MainWindow.xaml.cs
+++ b/XamlIn.Installer/Views/MainWindow.xaml.cs
@@ -1,16 +1,8 @@
11 using System;
2-using System.Collections.Generic;
3-using System.Linq;
4-using System.Text;
2+using System.Runtime.InteropServices;
53 using System.Windows;
6-using System.Windows.Controls;
7-using System.Windows.Data;
8-using System.Windows.Documents;
9-using System.Windows.Input;
10-using System.Windows.Media;
11-using System.Windows.Media.Imaging;
12-using System.Windows.Navigation;
13-using System.Windows.Shapes;
4+using System.Windows.Interop;
5+using Azyobuzi.XamlIn.Installer.ViewModels;
146
157 namespace Azyobuzi.XamlIn.Installer.Views
168 {
@@ -26,5 +18,52 @@ namespace Azyobuzi.XamlIn.Installer.Views
2618 {
2719 InitializeComponent();
2820 }
21+
22+ [DllImport("USER32.DLL")]
23+ private static extern IntPtr GetSystemMenu(IntPtr hWnd, UInt32 bRevert);
24+
25+ [DllImport("USER32.DLL")]
26+ private static extern bool AppendMenu(IntPtr hMenu, UInt32 uFlags, UInt32 uIDNewItem, string lpNewItem);
27+
28+ private const UInt32 MF_BYCOMMAND = 0x00000000;
29+ private const UInt32 MF_STRING = 0x00000000;
30+ private const UInt32 MF_SEPARATOR = 0x00000800;
31+ private const int WM_SYSCOMMAND = 0x112;
32+
33+ private void mainWindow_Loaded(object sender, RoutedEventArgs e)
34+ {
35+ var source = HwndSource.FromVisual(this) as HwndSource;
36+
37+ IntPtr hMenu = GetSystemMenu(source.Handle, 0);
38+
39+ AppendMenu(hMenu, MF_SEPARATOR, 0, string.Empty);
40+ AppendMenu(hMenu, MF_STRING, MF_BYCOMMAND, "&About Installation...");
41+
42+ source.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
43+ {
44+ if (msg == WM_SYSCOMMAND && ((uint)wParam) == MF_BYCOMMAND)
45+ {
46+ MessageBox.Show(
47+ "XamlIn\n\nproduct by @azyobuzin",
48+ "About Installation",
49+ MessageBoxButton.OK,
50+ MessageBoxImage.Information);
51+ handled = true;
52+ }
53+ return IntPtr.Zero;
54+ });
55+
56+ (this.DataContext as MainWindowViewModel).RaisedMessage += this.ReceiveMessage;
57+ }
58+
59+ private void ReceiveMessage(object sender, RaisedMessageEventArgs e)
60+ {
61+ switch (e.MessageKey)
62+ {
63+ case "Cancel":
64+ this.Close();
65+ break;
66+ }
67+ }
2968 }
3069 }
--- a/XamlIn.Installer/XamlIn.Installer.csproj
+++ b/XamlIn.Installer/XamlIn.Installer.csproj
@@ -63,9 +63,17 @@
6363 <Generator>MSBuild:Compile</Generator>
6464 <SubType>Designer</SubType>
6565 </ApplicationDefinition>
66+ <Compile Include="DelegateCommand.cs" />
67+ <Compile Include="Models\DialogPageCollection.cs" />
6668 <Compile Include="Models\File.cs" />
6769 <Compile Include="Models\FileCollection.cs" />
70+ <Compile Include="Models\IInstallAction.cs" />
71+ <Compile Include="Models\IUninstallAction.cs" />
6872 <Compile Include="Models\XamlIn.cs" />
73+ <Compile Include="ViewModels\ViewModelBase.cs" />
74+ <Compile Include="Views\DialogPages\StartPage.xaml.cs">
75+ <DependentUpon>StartPage.xaml</DependentUpon>
76+ </Compile>
6977 <Page Include="Views\MainWindow.xaml">
7078 <Generator>MSBuild:Compile</Generator>
7179 <SubType>Designer</SubType>
@@ -80,6 +88,10 @@
8088 <DependentUpon>MainWindow.xaml</DependentUpon>
8189 <SubType>Code</SubType>
8290 </Compile>
91+ <Page Include="Views\DialogPages\StartPage.xaml">
92+ <SubType>Designer</SubType>
93+ <Generator>MSBuild:Compile</Generator>
94+ </Page>
8395 </ItemGroup>
8496 <ItemGroup>
8597 <Compile Include="Properties\AssemblyInfo.cs">
@@ -109,6 +121,9 @@
109121 <ItemGroup>
110122 <Resource Include="install.ico" />
111123 </ItemGroup>
124+ <ItemGroup>
125+ <Resource Include="Images\MultimediaModern05.bmp" />
126+ </ItemGroup>
112127 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
113128 <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
114129 Other similar extension points exist, see Microsoft.Common.targets.