目次
Livetインストール
Livetのインストールをまとめました。必要な方は参考にしてください。
MVVMパターンによるLivetサンプルソース
標準のWPFプロジェクトからMVVMパターンを実装するのは困難な作業です。そんな時にMVVMの補助ライブラリ導入を検討すると思います。 MVVM Light Toolkit、Prism、Livetなどがありますが今回は国産のLivetを導入し、サンプルプログラムを作成しました。
サンプルソースの内容は以下のとおりです。.NET Framework4.5,Livet1.2.0
- TextBoxのGotFocus時に選択状態にしております。
- TextBox(1)のLostFocus時にTextBox(1)からTextBox(3)にコピー処理を行っています。
- クリア処理。TextBox(1)からTextBox(3),TextBlock背景色,選択したファイル名を初期状態に戻します。
- Windowの大きさを変更します。
- TextBlock背景色を変更します。
- ファイルダイアログを表示します。
- Windowを終了します。
※1.の処理は汎用的なBehaviorを作成したほうがいいと思います。
ビハインドコードには何もコードを書いていないので掲載いたしません。 (View)Sample3.xaml (ViewModel)Sample3ViewModel.cs (Model)Sample3Model.cs,Sample3ModelData.cs
スポンサーリンク
(View)Sample3.xaml
<Window x:Class="LivetWPFApplication1.Views.Sample3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
xmlns:l="http://schemas.livet-mvvm.net/2011/wpf"
xmlns:v="clr-namespace:LivetWPFApplication1.Views"
xmlns:vm="clr-namespace:LivetWPFApplication1.ViewModels"
Title="{Binding ModelData.WindowTitle}" Height="350" Width="525" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<vm:Sample3ViewModel/>
</Window.DataContext>
<!-- フォーカスがある TextBox の背景色を変更するスタイル -->
<Window.Resources>
<Style TargetType="{x:Type TextBox}">
<!--StyleにTrriggerを定義-->
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<!--IsFocusedがTrueの場合、下の値を適用-->
<Setter Property="Background" Value="LightCyan" />
</Trigger>
<Trigger Property="IsFocused" Value="False">
<Setter Property="Background" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<i:Interaction.Triggers>
<!--Viewに特別な要件が存在しない限りは、トリガーやアクションの自作にこだわらず積極的にコードビハインドを
使いましょう -->
<!--Viewのコードビハインドは、基本的にView内で完結するロジックとViewModelからのイベントの受信
(専用リスナを使用する)に限るとトラブルが少なくなります -->
<!--Livet1.1からはコードビハインドでViewModelのイベントを受信するためのWeakEventLisnterサポートが
追加されています -->
<!--WindowのContentRenderedイベントのタイミングでViewModelのInitializeメソッドが呼ばれます-->
<i:EventTrigger EventName="ContentRendered">
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="Initialize"/>
</i:EventTrigger>
<!--Windowが閉じたタイミングでViewModelのDisposeメソッドが呼ばれます-->
<i:EventTrigger EventName="Closed">
<l:DataContextDisposeAction/>
</i:EventTrigger>
<!--WindowのCloseキャンセル処理に対応する場合は、WindowCloseCancelBehaviorの使用を検討してください-->
<!--最大化-->
<l:InteractionMessageTrigger MessageKey="Maximize" Messenger="{Binding Messenger, Mode=OneWay}">
<l:WindowInteractionMessageAction/>
</l:InteractionMessageTrigger>
<!--普通-->
<l:InteractionMessageTrigger MessageKey="Normal" Messenger="{Binding Messenger, Mode=OneWay}">
<l:WindowInteractionMessageAction/>
</l:InteractionMessageTrigger>
<l:InteractionMessageTrigger MessageKey="Question" Messenger="{Binding Path=Messenger}">
<l:ConfirmationDialogInteractionMessageAction />
</l:InteractionMessageTrigger>
<l:InteractionMessageTrigger MessageKey="Close" Messenger="{Binding Messenger, Mode=OneWay}">
<l:WindowInteractionMessageAction/>
</l:InteractionMessageTrigger>
</i:Interaction.Triggers>
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="442,11,0,0" TextWrapping="Wrap"
Text="{Binding ModelData.WindowState}" VerticalAlignment="Top">
<TextBlock.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="LightBlue" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
<Label Content="(1) LostFocus(1=>3)" HorizontalAlignment="Left" Margin="22,10,0,0"
VerticalAlignment="Top"/>
<Label Content="(2)" HorizontalAlignment="Left" Margin="206,11,0,0" VerticalAlignment="Top"/>
<Label Content="(3)" HorizontalAlignment="Left" Margin="324,10,0,0" VerticalAlignment="Top"
RenderTransformOrigin="1.176,-2.08"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="22,40,0,0" TextWrapping="Wrap" VerticalAlignment="Top"
Width="120" Text="{Binding ModelData.Text01}">
<!--Triggers/TextBoxSetStateToSourceAction-->
<!--Behaviors/TextBoxBindingSupportBehavior-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<l:TextBoxSetStateToSourceAction Property="SelectionStart"
Source="{Binding ModelData.SelStartText01}"/>
<l:TextBoxSetStateToSourceAction Property="SelectionLength"
Source="{Binding ModelData.SelLengthText01}"/>
<l:TextBoxSetStateToSourceAction Property="SelectedText"
Source="{Binding ModelData.SelTextText01}"/>
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActSelect" MethodParameter="txt01"/>
</i:EventTrigger>
<i:EventTrigger EventName="LostFocus">
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActCopy"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
<l:TextBoxBindingSupportBehavior SelectionStart="{Binding ModelData.SelStartText01}"
SelectionLength="{Binding ModelData.SelLengthText01}" SelectedText="{Binding ModelData.SelTextText01}"/>
</i:Interaction.Behaviors>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="23" Margin="147,40,0,0" TextWrapping="Wrap" VerticalAlignment="Top"
Width="120"
Text="{Binding ModelData.Text02}">
<!--Triggers/TextBoxSetStateToSourceAction-->
<!--Behaviors/TextBoxBindingSupportBehavior-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<l:TextBoxSetStateToSourceAction Property="SelectionStart"
Source="{Binding ModelData.SelStartText02}"/>
<l:TextBoxSetStateToSourceAction Property="SelectionLength"
Source="{Binding ModelData.SelLengthText02}"/>
<l:TextBoxSetStateToSourceAction Property="SelectedText"
Source="{Binding ModelData.SelTextText02}"/>
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActSelect"
MethodParameter="txt02"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
<l:TextBoxBindingSupportBehavior SelectionStart="{Binding ModelData.SelStartText02}"
SelectionLength="{Binding ModelData.SelLengthText02}" SelectedText="{Binding ModelData.SelTextText02}"/>
</i:Interaction.Behaviors>
</TextBox>
<TextBox HorizontalAlignment="Left" Height="23" Margin="272,40,0,0" TextWrapping="Wrap" VerticalAlignment="Top"
Width="120"
Text="{Binding ModelData.Text03}">
<!--Triggers/TextBoxSetStateToSourceAction-->
<!--Behaviors/TextBoxBindingSupportBehavior-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<l:TextBoxSetStateToSourceAction Property="SelectionStart"
Source="{Binding ModelData.SelStartText03}"/>
<l:TextBoxSetStateToSourceAction Property="SelectionLength"
Source="{Binding ModelData.SelLengthText03}"/>
<l:TextBoxSetStateToSourceAction Property="SelectedText"
Source="{Binding ModelData.SelTextText03}"/>
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActSelect" MethodParameter="txt03"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<i:Interaction.Behaviors>
<l:TextBoxBindingSupportBehavior SelectionStart="{Binding ModelData.SelStartText03}"
SelectionLength="{Binding ModelData.SelLengthText03}" SelectedText="{Binding ModelData.SelTextText03}"/>
</i:Interaction.Behaviors>
</TextBox>
<Button Command="{Binding Path=ActClearCommand}" Content="クリア(ViewModelCommand)" HorizontalAlignment="Left"
Margin="22,77,0,0" VerticalAlignment="Top" Width="211"/>
<Button Content="普通-最大化(EventTrigger)" HorizontalAlignment="Left" Margin="238,77,0,0" VerticalAlignment="Top"
Width="211">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActMaximize"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button Command="{Binding Path=ActCloseCommand}" Content="終了(ViewModelCommand)" HorizontalAlignment="Left"
Margin="23,149,0,0" VerticalAlignment="Top" Width="211"/>
<Button Content="右のTextBlock背景色(EventTrigger)" HorizontalAlignment="Left" Margin="22,101,0,0"
VerticalAlignment="Top" Width="211">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:LivetCallMethodAction MethodTarget="{Binding}" MethodName="ActBackGround"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<TextBlock HorizontalAlignment="Left" Margin="238,103,0,0" TextWrapping="Wrap" Text="TextBlock背景色"
VerticalAlignment="Top" Width="211"
Background="{Binding ModelData.BackgroundTextBlock}"/>
<Button Content="ファイルダイアログ(ListenerCommand)" HorizontalAlignment="Left" Margin="22,125,0,0"
VerticalAlignment="Top" Width="211">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<l:OpenFileDialogInteractionMessageAction>
<l:DirectInteractionMessage CallbackCommand="{Binding OpenFileCommand, Mode=OneWay}">
<l:OpeningFileSelectionMessage Filter="テキストファイル(*.txt)|*.txt|すべてのファイル(*.*)|*.*"
Title="ファイルを開く" MultiSelect="False"/>
</l:DirectInteractionMessage>
</l:OpenFileDialogInteractionMessageAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<TextBlock HorizontalAlignment="Left" Margin="238,125,0,0" TextWrapping="Wrap"
Text="{Binding ModelData.TextTextBlock}" VerticalAlignment="Top" Width="251">
</TextBlock>
</Grid>
</Window>
(ViewModel)Sample3ViewModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Livet;
using Livet.Commands;
using Livet.Messaging;
using Livet.Messaging.IO;
using Livet.EventListeners;
using Livet.Messaging.Windows;
using LivetWPFApplication1.Models;
namespace LivetWPFApplication1.ViewModels
{
public class Sample3ViewModel : ViewModel
{
/* コマンド、プロパティの定義にはそれぞれ
*
* lvcom : ViewModelCommand
* lvcomn : ViewModelCommand(CanExecute無)
* llcom : ListenerCommand(パラメータ有のコマンド)
* llcomn : ListenerCommand(パラメータ有のコマンドCanExecute無)
* lprop : 変更通知プロパティ(.NET4.5ではlpropn)
*
* を使用してください。
*
* Modelが十分にリッチであるならコマンドにこだわる必要はありません。
* View側のコードビハインドを使用しないMVVMパターンの実装を行う場合でも、ViewModelにメソッドを定義し、
* LivetCallMethodActionなどから直接メソッドを呼び出してください。
*
* ViewModelのコマンドを呼び出せるLivetのすべてのビヘイビアトリガーアクションは
* 同様に直接ViewModelのメソッドを呼び出し可能です。
*/
/* ViewModelからViewを操作したい場合は、View側のコードビハインド無で処理を行いたい場合は
* Messengerプロパティからメッセージ(各種InteractionMessage)を発信する事を検討してください。
*/
/* Modelからの変更通知などの各種イベントを受け取る場合は、PropertyChangedEventListenerや
* CollectionChangedEventListenerを使うと便利です。各種ListenerはViewModelに定義されている
* CompositeDisposableプロパティ(LivetCompositeDisposable型)に格納しておく事でイベント解放を容易に行えます。
*
* ReactiveExtensionsなどを併用する場合は、ReactiveExtensionsのCompositeDisposableを
* ViewModelのCompositeDisposableプロパティに格納しておくのを推奨します。
*
* LivetのWindowテンプレートではViewのウィンドウが閉じる際にDataContextDisposeActionが動作するようになっており、
* ViewModelのDisposeが呼ばれCompositeDisposableプロパティに格納されたすべてのIDisposable型の
*インスタンスが解放されます。
*
* ViewModelを使いまわしたい時などは、ViewからDataContextDisposeActionを取り除くか、発動のタイミングを
*ずらす事で対応可能です。
*/
/* UIDispatcherを操作する場合は、DispatcherHelperのメソッドを操作してください。
* UIDispatcher自体はApp.xaml.csでインスタンスを確保してあります。
*
* LivetのViewModelではプロパティ変更通知(RaisePropertyChanged)やDispatcherCollectionを使ったコレクション変更通知は
* 自動的にUIDispatcher上での通知に変換されます。変更通知に際してUIDispatcherを操作する必要はありません。
*/
#region Model
//Model
private Sample3Model _Model;
private Sample3ModelData _ModelData;
#endregion
#region コンストラクタ
/// <summary>
/// コンストラクタ
/// </summary>
public Sample3ViewModel()
{
//Modelインスタンス作成
_ModelData = new Sample3ModelData();
_Model = new Sample3Model(_ModelData);
}
#endregion
#region Livet初期処理
public void Initialize()
{
//Item設定初期処理
ActClear();
}
#endregion
#region TextBox選択状態処理
/// <summary>
/// TextBox選択状態処理
/// <param name="pName">名称(string)</param>
/// </summary>
public void ActSelect(string pName)
{
_Model.ActSelect(pName);
RaisePropertyChanged("ModelData");
}
#endregion
#region コピー(1=>3)処理
/// <summary>
/// コピー(1=>3)処理
/// </summary>
public void ActCopy()
{
_Model.ActCopy();
RaisePropertyChanged("ModelData");
}
#endregion
#region コピー(1=>3)処理
/// <summary>
/// Window最大化処理(普通<=>最大化)(EventTriggerパターン)
/// </summary>
public void ActMaximize()
{
if (_ModelData.WindowState=="普通")
{
_Model.ActMaximize("最大化");
RaisePropertyChanged("ModelData");
Messenger.Raise(new WindowActionMessage(WindowAction.Maximize, "Maximize"));
}
else
{
_Model.ActMaximize("普通");
RaisePropertyChanged("ModelData");
Messenger.Raise(new WindowActionMessage(WindowAction.Normal, "Normal"));
}
}
#endregion
#region ModelData変更通知プロパティ
public Sample3ModelData ModelData
{
get
{ return _ModelData; }
set
{
if (_ModelData == value)
return;
_ModelData = value;
RaisePropertyChanged("ModelData");
}
}
#endregion
#region ActClearCommand(クリア)
/// <summary>
/// クリア処理
/// </summary>
private ViewModelCommand _ActClearCommand;
public ViewModelCommand ActClearCommand
{
get
{
if (_ActClearCommand == null)
{
_ActClearCommand = new ViewModelCommand(ActClear);
}
return _ActClearCommand;
}
}
public void ActClear()
{
_Model.InitializeItem();
RaisePropertyChanged("ModelData");
}
#endregion
#region ActCloseCommand
/// <summary>
/// 終了処理MessageBox(Yes/No)(ViewModelCommandパターンViewModel->View)
/// </summary>
private ViewModelCommand _ActCloseCommand;
public ViewModelCommand ActCloseCommand
{
get
{
if (_ActCloseCommand == null)
{
_ActCloseCommand = new ViewModelCommand(ActClose);
}
return _ActCloseCommand;
}
}
private void ActClose()
{
_Model.ActClose();
var result = this.Messenger.GetResponse<ConfirmationMessage>(
new ConfirmationMessage(_Model.Message, _ModelData.WindowTitle,
_Model.MsgBoxImage, _Model.MsgBoxButton, "Question"));
if ((result.Response.HasValue) && (result.Response.Value))
{
Messenger.Raise(new WindowActionMessage(WindowAction.Close, "Close"));
}
}
#endregion
#region ActBackGround
/// <summary>
/// TextBlock BackGround変更処理
/// </summary>
public void ActBackGround()
{
_Model.ActBackground();
RaisePropertyChanged("ModelData");
}
#endregion
#region OpenFileCommand
/// <summary>
/// 「ファイルを開く」ダイアログ表示
/// </summary>
private ListenerCommand<OpeningFileSelectionMessage> _OpenFileCommand;
public ListenerCommand<OpeningFileSelectionMessage> OpenFileCommand
{
get
{
if (_OpenFileCommand == null)
{
_OpenFileCommand = new ListenerCommand<OpeningFileSelectionMessage>(OpenFile);
}
return _OpenFileCommand;
}
}
public void OpenFile(OpeningFileSelectionMessage parameter)
{
if (parameter.Response != null)
{
_Model.OpenFile(parameter.Response[0]);
RaisePropertyChanged("ModelData");
}
}
#endregion
}
}
(Model)Sample3Model.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using Livet;
namespace LivetWPFApplication1.Models
{
public class Sample3Model : NotificationObject
{
/*
* NotificationObjectはプロパティ変更通知の仕組みを実装したオブジェクトです。
*/
//Model
private Sample3ModelData _ModelData;
private string _Message;
private MessageBoxImage _MsgBoxImage;
private MessageBoxButton _MsgBoxButton;
//TextBlockのBackground
private Brush _SvBackgroundTextBlock;
#region コンストラクタ
/// <summary>
/// コンストラクタ
/// <param name="pModelData">データ(Sample3ModelData)</param>
/// </summary>
public Sample3Model(Sample3ModelData pModelData)
{
_ModelData = pModelData;
//Window設定初期処理
InitializeWindow();
}
#endregion
#region Window設定初期処理
/// <summary>
/// Window設定初期処理
/// </summary>
private void InitializeWindow()
{
//タイトルの設定等(Window周り)
_ModelData.WindowTitle = "WPF+Livet Sample Ver1.0.4";
_ModelData.WindowState = "普通";
//TextBlockのBackgroundを退避
_SvBackgroundTextBlock = _ModelData.BackgroundTextBlock;
}
#endregion
#region Item設定初期処理
/// <summary>
/// Item設定初期処理
/// </summary>
public void InitializeItem()
{
//項目別初期処理
//TextBox01
_ModelData.Text01 = string.Empty;
_ModelData.SelStartText01 = 0;
_ModelData.SelLengthText01 = _ModelData.Text01.Length;
_ModelData.SelTextText01 = _ModelData.Text01;
//TextBox02
_ModelData.Text02 = string.Empty;
_ModelData.SelStartText02 = 0;
_ModelData.SelLengthText02 = _ModelData.Text02.Length;
_ModelData.SelTextText02 = _ModelData.Text02;
//TextBox03
_ModelData.Text03 = string.Empty;
_ModelData.SelStartText03 = 0;
_ModelData.SelLengthText03 = _ModelData.Text03.Length;
_ModelData.SelTextText03 = _ModelData.Text03;
//Backgroundを退避より戻す
_ModelData.BackgroundTextBlock = _SvBackgroundTextBlock;
_ModelData.TextTextBlock = "選択したファイル名をここに表示します。";
}
#endregion
#region TextBox選択状態処理
/// <summary>
/// TextBox選択状態処理
/// <param name="pName">名称(string)</param>
/// </summary>
public void ActSelect(string pName)
{
switch (pName)
{
case "txt01":
_ModelData.SelStartText01 = 0;
_ModelData.SelLengthText01 = _ModelData.Text01.Length;
_ModelData.SelTextText01 = _ModelData.Text01;
break;
case "txt02":
_ModelData.SelStartText02 = 0;
_ModelData.SelLengthText02 = _ModelData.Text02.Length;
_ModelData.SelTextText02 = _ModelData.Text02;
break;
case "txt03":
_ModelData.SelStartText03 = 0;
_ModelData.SelLengthText03 = _ModelData.Text03.Length;
_ModelData.SelTextText03 = _ModelData.Text03;
break;
}
}
#endregion
#region コピー(1=>3)処理
/// <summary>
/// コピー(1=>3)処理
/// </summary>
public void ActCopy()
{
_ModelData.Text03 = _ModelData.Text01;
}
#endregion
#region コピー(1=>3)処理
/// <summary>
/// Window最大化処理(普通<=>最大化)
/// <param name="pState">Window状態(string)</param>
/// </summary>
public void ActMaximize(string pState)
{
_ModelData.WindowState = pState;
}
#endregion
#region 終了処理
/// <summary>
/// 終了処理
/// </summary>
public void ActClose()
{
//チェック等
GetMessage("Close");
}
#endregion
#region メッセージ取得処理
/// <summary>
/// メッセージ取得処理
/// <param name="pPara">処理種別(string)</param>
/// </summary>
private void GetMessage(string pPara)
{
switch (pPara)
{
case "Close":
_Message = "本当にWindowを閉じますか?";
_MsgBoxImage = MessageBoxImage.Question;
_MsgBoxButton = MessageBoxButton.YesNo;
break;
}
}
#endregion
#region TextBlock背景色処理
/// <summary>
/// TextBlock背景色処理
/// </summary>
public void ActBackground()
{
_ModelData.BackgroundTextBlock = new SolidColorBrush(Colors.Red);
}
#endregion
#region OpenFile設定処理
/// <summary>
/// OpenFile設定処理
/// <param name="pName">ファイルフルパス(string)</param>
/// </summary>
public void OpenFile(string pName)
{
_ModelData.TextTextBlock = pName;
}
#endregion
#region Messageプロパティ
/// <summary>
/// Messageプロパティ
/// </summary>
public string Message
{
get
{
return _Message;
}
}
#endregion
#region MsgBoxImageプロパティ
/// <summary>
/// MsgBoxImageプロパティ
/// </summary>
public MessageBoxImage MsgBoxImage
{
get
{
return _MsgBoxImage;
}
}
#endregion
#region MsgBoxButtonプロパティ
/// <summary>
/// MsgBoxButtonプロパティ
/// </summary>
public MessageBoxButton MsgBoxButton
{
get
{
return _MsgBoxButton;
}
}
#endregion
}
}
(Model)Sample3ModelData.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace LivetWPFApplication1.Models
{
public class Sample3ModelData
{
//Window関連
public string WindowTitle { get; set; }
public string WindowState { get; set; }
public Brush BackgroundTextBlock { get; set; }
public string TextTextBlock { get; set; }
//各項目
public string Text01 { get; set; }
public int SelStartText01 { get; set; }
public int SelLengthText01 { get; set; }
public string SelTextText01 { get; set; }
//各項目
public string Text02 { get; set; }
public int SelStartText02 { get; set; }
public int SelLengthText02 { get; set; }
public string SelTextText02 { get; set; }
//各項目
public string Text03 { get; set; }
public int SelStartText03 { get; set; }
public int SelLengthText03 { get; set; }
public string SelTextText03 { get; set; }
}
}
お読みくださってありがとうございました。それでは。