2015年12月24日木曜日

テーマ別にリソースを定義して使用する

テーマ別のリソースを定義

 
  
   
   
  
  
   
   
  
  
 
 :

xaml で使用するときは ThemeResource を付加する



コードでリソースを使用するには
// テーマの ResourceDictionary は次のように得る
var rdic = Application.Current.Resources.ThemeDictionaries[RequestedTheme.ToString()] as ResourceDictionary;
// 得られた ResourceDictionary から使用するリソースを得る
Brush br = rdic["UnselectDataBackGround"] as Brush;

2015年12月23日水曜日

1行に複数の項目を配置するListBoxのSample(その3)

コンバーターを使用してデータの表示を変える

ID の表示を ID[9999] のように表示する。
ListItem.cs 内にコンバータクラスを作成する。
class IDFormatter : Windows.UI.Xaml.Data.IValueConverter
{
 public object Convert(object value, Type targetType, object parameter, string language)
 {
  if (value is uint) {
   return "ID[" + ((uint)value).ToString("D4") + "]";
  }
  return "";
 }
 public object ConvertBack(object value, Type targetType, object parameter, string language)
 {
  throw new NotImplementedException();
 }
}


MainPage.xaml に作成したコンバータを使用するように記述する。
<Page
                      :
 xmlns:data="using:ListBoxSample.Model"
 xmlns:formatter="using:ListBoxSample.Model"
 mc:Ignorable="d">



<TextBlock Text="{x:Bind ID, Converter={StaticResource IDFormatterKey}
        ConverterParameter=Param}" 
 Style="{ThemeResource BaseTextBlockStyle}" />
のようにパラメータを指定すると
public object Convert(object value, Type targetType, object parameter, string language)
の parameter に記述した文字列(例では"Param")が渡される。
ただし、現状では文字列でしか渡せないので、使い道が限定される。
ここもBindできれば、できることが増えそうだが....
この Converter で動的なパラメータ(フラグ等)で変換方法を変えるには、Globalなフラグでしか出来ない。


1行に複数の項目を配置するListBoxのSample(その2)

行のフォーマット

styleを使用して行の幅を調整する

 
  
   
  
 



行の高さも調整する


MinHeight / Padding も指定しないとうまくいかない。



テキストの色を条件によって変える

ListItemクラスに色を持つプロパティを追加(Nameに色を付ける)
public Brush NameColor {
 get { return (ID&1) == 0 ?
  new SolidColorBrush(Colors.Red) :
  new SolidColorBrush(Colors.Green);
 }
}

このサンプルでは ID が偶数・奇数で色を変えている


TextBlockにbindする
<TextBlock Text="{x:Bind Name}"
 Foreground="{x:Bind NameColor}"
 Style="{ThemeResource BaseTextBlockStyle}"  Grid.Column="2"/>


2015年12月20日日曜日

1行に複数の項目を配置するListBoxのSample(その1)

表示するデータの構造(Model)のクラスを作成

Modelフォルダを作りそこに、"新しい項目の追加>クラス" で、ListItem.cs を作成。
作られたファイルは次のようになっている。
namespace ListBoxSample.Model
{
 class ListItem
 {
 }
}

これに、表示する項目に対応するプロパティと、簡単なコンストラクタを追加する。
class ListItem
{
 public uint ID { get; private set; }
 public string Name { get; set; }
 public char Label { get { return char.ToUpper(Name[0]); } }
 public string Comment { get; set; }

 static private uint NextID = 0;

 public ListItem(string name, string comment)
 {
  ID = ++NextID;
  Name = name;
  Comment = comment;
 }
}


MainPage.xaml にModel を登録

<Page
 x:Class="ListBoxSample.MainPage"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="using:ListBoxSample"
 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 xmlns:data="using:ListBoxSample.Model"
 mc:Ignorable="d">

xmlns:data の data は任意の名称なのでわかりやすい名称をつけられる。


1項目に表示するテンプレートを作成する(MainPage.xaml)


 
 
  
   
    
    
    
    
   
   
   
   
   
  
 


行に当たる Grid の背景を LawnGreen にしている。

MainPageにListBox を配置し、作成したテンプレートを登録する(MainPage.xaml)


for (int i=0; i<10 data-blogger-escaped-comment="" data-blogger-escaped-i="" data-blogger-escaped-listitem="" data-blogger-escaped-listitems.add="" data-blogger-escaped-name="" data-blogger-escaped-new="" data-blogger-escaped-ostring="" data-blogger-escaped-pre="" data-blogger-escaped-string="">

ListBoxの背景を Aqua にしている。



リストに表示するアイテムのコレクションを作成(MainPage.xaml.cs)

 作成したコレクションのオブジェクトをListBoxのソースとして指定する。
private ObservableCollection ListItems;

public MainPage()
{
 this.InitializeComponent();
 
 ListItems = new ObservableCollection();
 listBox.ItemsSource = ListItems;
}

ListBoxにアイテムを追加する(MainPage.xaml.cs)

for (int i=0; i<10 data-blogger-escaped-comment="" data-blogger-escaped-i="" data-blogger-escaped-listitem="" data-blogger-escaped-listitems.add="" data-blogger-escaped-name="" data-blogger-escaped-new="" data-blogger-escaped-ostring="" data-blogger-escaped-pre="" data-blogger-escaped-string="">


ここまでで1行に4項目があるListBoxが出来たが、 行の項目間が詰まっているの次回で修正する。

2015年12月15日火曜日

xaml で定義したコントロールを public にするには


x:FieldModifier="Public" をつけると public メンバーになる。




2015年12月12日土曜日

サウンドファイルを再生する

Assets フォルダに使用するサウンドファイルを配置する。
MainPage.xaml に再生するファイルを登録

 


再生する
 SoundClick1.Volume = 0.5;  // ボリュームの指定は 0 ~ 1 の間
 SoundClick1.Play();    // 再生


ボタンが押された時に音を鳴らすようにした時、上記のように再生すれば音は出るが、
連続して押されるとまだ前のサウンドが再生中のとき重ねて音は出ない。
これを回避するにはxamlで同じファイルを2つ登録しておいて



これを交互に再生するようにすれば良いと思う。
private MediaElement[] PlayClickSound = new MediaElement[2];

// 初期化
PlayClickSound[0] = SoundClick11;
PlayClickSound[1] = SoundClick12;
SoundCount = 0;

// クリックハンドラ
PlayClickSound[SoundCount%2].Play();  // 再生して
++SoundCount;
PlayClickSound[SoundCount%2].Stop();  // 前のサウンドは停止させる

2015年12月8日火曜日

設定データのSaveとLoad

設定データをSaveする。
Windows.Storage.ApplicationDataContainer localSettings =
 Windows.Storage.ApplicationData.Current.LocalSettings;

localSettings.Values["Test"] = 12345;  // ”Test"というKeyでInt 12345 を保存

設定したデータはすぐにファイルへ書き込まれる。

設定データをLoadする。
Windows.Storage.ApplicationDataContainer localSettings = 
 Windows.Storage.ApplicationData.Current.LocalSettings;
int? data = localSettings.Values["Test"] as int?;  // "Test"というKeyのデータを読み込む
if (data == null)    // データが存在しなければ 0 にする
 data = 0;

設定ファイルはインストールされたフォルダ下の
  Settings\Settings.data

2015年12月7日月曜日

クリップボードからテキストを取得

DataPackageView dpv = Clipboard.GetContent();
if (dpv.Contains(StandardDataFormats.Text)) {
 var text = await dpv.GetTextAsync();
}

テキストをクリップボードへセット

DataPackage dp = new DataPackage();
dp.RequestedOperation = DataPackageOperation.Copy;
dp.SetText("Text");
Clipboard.SetContent(dp);

2015年12月3日木曜日

TextBlock で表示する文字列の幅・高さを求める

TextBlockが置かれている領域のサイズを sizeArea に入れておき
  textBlock.Measure(sizeArea);
としてコールすると
textBlock.DesiredSize にその領域で表示されるサイズが返される。

サンプル
TextBlock を Border 内に配置し、Border内に収まるようにフォントサイズを調整する。
// 最大のフォントサイズ
textBlock.FontSize = 42;

// Borderの領域サイズ
Size    szBorder = new Size(border.ActualWidth, border.ActualHeight);

// 配置したTextBlockのマージンを考慮した表示できる最大の幅
double  MaxWidth = szBorder.Width - (textBlock.Margin.Left + textBlock.Margin.Right);

while (true) {
    textBlock.Measure(szBorder);    // 現在の文字列での表示幅を得る
    if (textBlock.DesiredSize.Width < MaxWidth)
        break;                      // 最大幅よりも小さければOK
    textBlock.FontSize -= 2;        // はみ出しているときはフォントサイズを小さくする
}

高さの値(textBlock.DesiredSize.Height)はあてにならないような...

2015年12月2日水曜日

テキストファイルを読む

インストールされているフォルダの test.txt ファイルを読む(Unicode)
Uri uri = new System.Uri("ms-appx:///test.txt");
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
using (Stream stream = (await file.OpenReadAsync()).AsStream()) {
    using (TextReader reader = new StreamReader(stream)) {
        textBox.Text = await reader.ReadToEndAsync();
    }
}
Shift-JISのファイルを読むにはEncoderを指定する
Uri uri = new System.Uri("ms-appx:///test.txt");
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(uri);
using (Stream stream = (await file.OpenReadAsync()).AsStream()) {
    var enc = System.Text.Encoding.GetEncoding("Shift_JIS");
    using (TextReader reader = new StreamReader(stream, enc)) {
        textBox.Text = await reader.ReadToEndAsync();
    }
}
デフォルトでは Shift-JIS のEncoderが取得できない(例外が発生する)。
デフォルト以外のエンコードを使用するには、Applicationの初期化などで次の関数をコールしておく。
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);

特定のフォルダ以外のファイル(直接パスを指定して)は読むことが出来ない
"毎回"ファイルピッカーを表示ユーザーに指定してもらうしかないらしい。
これは保存時でも同じで、"上書き保存"という動作さえも出来ない。
ファイルを使うアプリはユーザーから見ても使いづらいことになっているようだ。

15/12/08 追記
StorageApplicationPermissions.FutureAccessList を使用して一度ユーザーに指定されたファイルを保存しておくことができるようだ。
これを用いれば次回アプリケーションが起動した時にそのファイルを使用したりすることが可能。