スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: スポンサー広告

Transform

仕事で画面のズームを実装する事になったので、WPFのTransformについて色々調べた事がある。
↓の記事、日付は古いけど、わかりやすいです。
RenderTransformプロパティとLayoutTransformプロパティの違い
ズーム機能を作った時、RenderTransformで試そうとしたけど、上手くいかなかった(というか、理解が足らずどう実装していいかもわからなかった)。結局はLayoutTransformで実装した(そっちの実装が簡単だったので)。
ズームではないけど、2つの違いを見るために書いてみた。続きを読む
スポンサーサイト
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

[資料的情報]TypeScript

Microsoftがなんか出してた。
MSがJavaScriptの弱点補う新言語
本家のサイトは↓
Welcome to TypeScript
うーん。Javascriptに毛の生えたようなものなのか。それ以上なのか。C#とJavascriptの2つを覚えたくない人向けなのか。人の話す言語と違い、ほいほい出てくるなぁ。
TypeScriptとVisualStdio2012とは連携できるようだけど。
今はまだ、TypeScriptの文法で書くくらいなら、Javascript(主にJQuery)を書けた方が良いような気がする。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WEB | コメント: 0 | トラックバック: 0

[資料的情報]ついに出ましたか。

Window.Formsでは結構お世話になったGrapeCityさんが、WPFでもSpreadを正式リリースしたようです。
SPREAD for WPF
テンプレート有りきとは言いながら、行の多段組までできるようで。
うーん。ここまでやれるって事は、標準のDataGridではなく、完全自作なんだろうなぁ。
気になるのは、パフォーマンスかな。後はバグか。
まだバージョン1.0Jなので、試しに使う分にはいいかもしれない。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

その行(DataGridRow)が、DataGridの表示領域内にあるかどうか

DataGridには、DataGridの行(DataGridRow)が表示領域(Viewport)にあるかどうか?みたいなメソッドがない。UI仮想化の設定がなければ、すべての行に実体があり、見えていようといまいと、IsVisible=trueだったりする。UI仮想化があったとしても、CurrentCellがある行には隠れていても実体があり、実際の特定は難しい。
作ってみましたとも(参)で作った、セルのマージ処理の改良時に、それが正確にわからないものかと調べていたら、いいのがあった。
Counting the number of visible rows in a DataGrid

/// <summary>
/// 指定のDataGridRowオブジェクトが表示されているか(ViewPort内にあるかどうか)を取得します。
/// </summary>
/// <param name="dataGrid">DataGridオブジェクト</param>
/// <param name="dataGridRow">チェック対象となるDataGridRowオブジェクト</param>
/// <returns>true:表示領域内にある</returns>
public static bool IsInViewPort(this DataGrid dataGrid, DataGridRow dataGridRow) {

//そもそもVisible設定がOFFになっている。
if (dataGridRow == null || !dataGridRow.IsVisible) {
return false;
}

//座標変換(おそらくDataGridからの相対的な座標に変換する)
var bounds = dataGridRow.TransformToAncestor(dataGrid).
TransformBounds(new Rect(0, 0,
dataGridRow.ActualWidth,
dataGridRow.ActualHeight));
//DataGrid自身の領域
var rect = new Rect(0, 0, dataGrid.ActualWidth, dataGrid.ActualHeight);
//DataGrid内の領域に含まれていれば、ViewPoprt内にあるとみなせる。
return rect.Contains(bounds.TopLeft) || rect.Contains(bounds.BottomRight);
}

このメソッドを使ったお陰で処理精度があがった。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

作ってみましたとも(参)。

作ってみましたのその参。セル結合。セルマージとも言う。欲しくて色々探してもなかったので、ほぼオリジナル。
20121215_1
「苗字」列がそれっぽく見える筈。続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

繰り返し文をLINQっぽく

プログラミングにおいては、基本でありメジャーである繰り返し文。Cで言えばfor文。
.NET1.1の頃は、
for (int i = 0; i < 100; i ++) {
//...
}

foreach (var item in list) {
//...
}
というものだった。(他にもdoやwhileもある)。
C#2.0でGenericができ、C#3でLINQやラムダ式が追加されてからは、以下のような書き方もできる。

var list1 = new []{1, 2, 3};
Array.ForEach(list1, elem => {
//...
});
ただし、これは配列だけ。

var list2 = new List<int>(3){1, 2, 3};
list2.ForEach(elem => {
//...
});
ただし、これはList<>専用。
LINQにはSelectはあってもForEach的なメソッドが見当たらない。まあ、目的が微妙に異なるからかもしれないけど。じゃ、ないなら作ろうという事で、以下の3種類を作ってみた。続きを読む
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 0 | トラックバック: 0

AはBである

AはBである
このインスタンス(A)はクラスBである。
class B {
//...
}
var A = new B();
var aIsB = A is B;//当然true

このインスタンス(A)はインターフェイスCである。
interface C {
//...
}
class B : C {
//...
}
var A = new B();
var AIsC = A is C;//true

インスタンスではなくタイプを使う(タイプのみ与えられる)場合

class C {
//...
}
class B : C {
//...
}
var A = new B();
var AIsExtendFromC = typeof(C).IsAssignableFrom(A.GetType());//true
var D = new C();
var DIsExtendFromC = typeof(C).IsAssignableFrom(D.GetType());//true

めんどくさいのはGenericが使用されている場合だった。仕事上、「Nullable<>を継承した値型のインスタンスかどうか?」を知りたい状況があった。

int? A = 3;
var AisNullableInt = A is Nullable<int>;//true
なんだけど、もっと大きいグループで比較したかった(int?とかdecimal?は、Nullable<int>やNullable<decimal>なので、より抽象っぽい「Nullable<>かどうか?」を知りたい)。これをどうするれば、思うような結果が得られるかで結構悩んだ。結果的には、↓のような感じになる。

var isNullable1 = typeof(Nullable<>).IsAssignableFrom(
typeof(int?).GetGenericTypeDefinition());//true
var isNullable2 = typeof(Nullable<>).IsAssignableFrom(
typeof(decimal?).GetGenericTypeDefinition());//true
これを利用することで、プロパティの型がNullable<>系かどうかがわかったりする。

class C {
public int? MyProperty {get; set;}
}

var propInfo = typeof(C).GetProperty("MyProperty");
var isNullable = typeof(Nullable<>).IsAssignableFrom(
propInfo.PropertyType.GetGenericTypeDefinition());//true
ただし、GenericではないTypeでGetGenericTypeDefinition()を呼び出すと、InvalidOperationExceptionを発生させるので、条件なしで使用というのは難しい。なので、厳密には

var propInfo = typeof(C).GetProperty("MyProperty");
if (propInfo.PropertyType.IsGenericType) {
var isNullable = typeof(Nullable<>).IsAssignableFrom(
propInfo.PropertyType.GetGenericTypeDefinition());
}
となる。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 0 | トラックバック: 0

値を比較する方法

Comparing Values for Equality in .NET: Identity and Equivalence
値が同じかどうかを判別する方法には、何通りか用意されている…らしい。

①a == b
②a.Equals(b)
③object.Equals(a, b)
④object.ReferenceEquals(a, b)

③は、a, bいずれかがnullでも比較可能にするためのメソッドかな。
④は、値が等しいかというより、参照先のメモリアドレスが同じかどうかかな。

int val1 = 10;
object obj1 = val1;
object obj2 = val1;

var isEqual1 = obj1 == obj2;//false
var isEqual2 = obj1.Equals(obj2);//true
var isEqual3 = object.Equals(obj1, obj2);//true
var isEqual4 = object.ReferenceEquals(obj1, obj2);//false

intは値型なので、obj1, obj2に渡されるのはアドレスではなく、値になる。なのでisEqual4はfalseになる。それはわかるけど、==もfalseになるんだな。という事は、C#もJavaと同じで==はメモリアドレス参照になるのか。
↑のリンクでは、以下の比較も行なっている

object val2 = 10;
object obj3 = val2;
object obj4 = val2;

var isEqual6 = obj3 == obj4;//true
var isEqual7 = obj3.Equals(obj4);//true
var isEqual8 = object.Equals(obj3, obj4);//true
var isEqual9 = object.ReferenceEquals(obj3, obj4);//true

元々がobjectとして扱っているので、obj3,obj4は同じメモリアドレスを参照することになるという事か。ちなみに、string型の場合。

string str1 = "AAA";
string str2 = "aaaa".ToUpper().Substring(0, 3);

var isEqualA = str1 == str2;//true
var isEqualB = str1.Equals(str2);//true
var isEqualC = object.Equals(str1, str2);//true
var isEqualD = object.ReferenceEquals(str1, str2);//false
string型を比較した場合、ReferenceEquals=false(比較先のメモリアドレスが異なる)でも、==はtrueになるようだ。でも、object型で扱うと、↓のような結果になる。

object str1 = "AAA";
object str2 = "aaaa".ToUpper().Substring(0, 3);

var isEqualA = str1 == str2;//false
var isEqualB = str1.Equals(str2);//true
var isEqualC = object.Equals(str1, str2);//true
var isEqualD = object.ReferenceEquals(str1, str2);//false
object型で扱う限り、==はメモリアドレス参照が同じかどうかを判定する。汎用化の為にstaicメソッド化する時、objectとして扱う場合は注意が必要、という事かな。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: C# | コメント: 0 | トラックバック: 0

マルチヘッダDataGridメモ-四(内部実装)

・Contentプロパティの変更用メソッドをオーバーライドする。
 Contentプロパティ(中身)の変更と共に処理を実装します。

/// <summary>対象となるDataGridオブジェクト</summary>
private DataGrid targetDataGrid_;

/// <summary>
/// 中身(Content)が変更された時に発生するイベント用のメソッド
/// </summary>
/// <param name="oldContent">旧コンテンツ</param>
/// <param name="newContent">新コンテンツ</param>
protected override void OnContentChanged(object oldContent, object newContent) {
base.OnContentChanged(oldContent, newContent);

if (this.targetDataGrid_ != null) {
this.ClearBindings();

///HACK:ここで登録したイベントハンドラを削除します

this.targetDataGrid_ = null;
}

if (newContent != null) {
this.targetDataGrid_ = newContent as DataGrid;

if (this.targetDataGrid_ != null) {

if (!this.targetDataGrid_.IsLoaded) {
this.targetDataGrid_.Loaded +=
new RoutedEventHandler(TargetDataGrid_Loaded);
} else {
this.TargetDataGrid_Loaded(this.targetDataGrid_,
new RoutedEventArgs());
}
}
}

return;
}

・DataGridのLoadに合わせて、処理を実装する。

/// <summary>
/// 対象となるDataGridのLoadedイベントハンドラ
/// </summary>
/// <param name="sender">イベント発生元(DataGrid)</param>
/// <param name="e">イベントデータ</param>
private void TargetDataGrid_Loaded(object sender, RoutedEventArgs e) {

var dataGrid = sender as DataGrid;
dataGrid.Loaded -= new RoutedEventHandler(TargetDataGrid_Loaded);
//各イベントにハンドラを登録します。
//サイズ変更イベント(SizeChanged)
//列表示インデックス変更イベント(ColumnDisplayIndexChanged)

//セル用パネルの水平方向オフセット
//主に、DataGridRowHeaderの幅になります。
//DataGrid側のプロパティとバインディングして、連動させます。
//CellsPanelHorizontalOffset
//NonFrozenColumnsViewportHorizontalOffset
//Background
//BorderBrush

//境界線幅の変更を監視します。

if (dataGrid.Template != null) {
//DataGrid内のスクロールビューワを探します。
//スクロールバー(垂直方向)の可視性(Visibility)と連動させます。
//スクロールの幅ともバインディングさせます。
//DataGridヘッダが使用しているボーダー(Border)のクラスタイプを確保します。
}

if (this.Template != null) {

var counter = CommonClosure.CountUp(0);

if (dataGrid.FrozenColumnCount > 0) {
//固定列有り
//→固定列側のマルチヘッダを構築します。
}

//可変列側のマルチヘッダを構築します。
}

return;
}

・サイズ変更イベント
 DataGridのサイズが変更されるので、マルチヘッダの各幅も再計算します。
・列表示インデックス変更イベント
 DataGridの列が入れ替わったという事なので、これも再計算を実行します。
・マルチヘッダの構築
 列の数だけ、ColumnDefinitionを用意する。
 マルチヘッダの一番の外枠をBorderとして、Borderを追加していく。
 Headerの内容が同じかどうかを検証し、ColumnSpanの値を決めて、 Borderに追加していく。
当サイトは基本をすっ飛ばしてます。基本文法等は、@ITをどうぞ
カテゴリー: WPF4 | コメント: 0 | トラックバック: 0

サイドバー背後固定表示サンプル

当ブログに書かれたソースコードは流用自由です。

バグ、スペルミス等はありうる事です。

ご利用の際は自己責任でお願いしますm(_ _)m

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。