C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[5]: WPF 改善方法


(過去ログ 69 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■40002 / inTopicNo.1)  WPF 改善方法
  
□投稿者/ NICO (1回)-(2009/08/19(Wed) 13:42:31)

分類:[.NET 全般] 

はじめまして。

WPFで、以下のように9マス分の各コントロールのプロパティを用意していますが、もっとスマートな方法がありますでしょうか?
1マス分のコントロール構成はすべて同じです。(StackPanel、Image、TextBlock)

初心者のため、他に方法が思いつきません。。
どなたかわかりましたら、ご教授お願いいたします。

---------------------------------------------------------------------------------------------------------------------------------------
★XAML★
<StackPanel Grid.Column="0" Grid.Row="0" Orientation="Vertical" Margin="5,5,5,5">
 <Image Source="{Binding Path_1}" Height="70" Width="70"></Image>
 <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" MaxWidth="90" FontSize="10" Text="{Binding Text_1}"></TextBlock>
</StackPanel>

<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Vertical" Margin="5,5,5,5">
 <Image Source="{Binding Path_2}" Height="70" Width="70"></Image>
 <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" MaxWidth="90" FontSize="10" Text="{Binding Text_2}"></TextBlock>
</StackPanel>

<StackPanel Grid.Column="0" Grid.Row="2" Orientation="Vertical" Margin="5,5,5,5">
 <Image Source="{Binding Path_3}" Height="70" Width="70"></Image>
 <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" MaxWidth="90" FontSize="10" Text="{Binding Text_3}"></TextBlock>
</StackPanel>

	・
	・(省略)
	・
	・

<StackPanel Grid.Column="2" Grid.Row="2" Orientation="Vertical" Margin="5,5,5,5">
 <Image Source="{Binding Path_9}" Height="70" Width="70"></Image>
 <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" MaxWidth="90" FontSize="10" Text="{Binding Text_9}"></TextBlock>
</StackPanel>

★C#★
private string path_1 = null;
public string Path_1 { get { return path_1; } }
private string text_1 = null;
public string Text_1 { get { return text_1; } }
	・
	・(省略)
	・
	・
private string path_9 = null;
public string Path_9 { get { return path_9; } }
private string text_9 = null;
public string Text_9 { get { return text_9; } }


---------------------------------------------------------------------------------------------------------------------------------

どうぞよろしくお願いいたします。

引用返信 編集キー/
■40010 / inTopicNo.2)  Re[1]: WPF 改善方法
□投稿者/ kazuto (13回)-(2009/08/19(Wed) 14:24:19)
kazuto さんの Web サイト
2009/08/19(Wed) 14:29:21 編集(投稿者)
Gridの構成が良く分かりませんが、以下のように均等配置を推測した上で。

---------------
   |   |   |
---------------
   |   |   |
---------------
   |   |   |
---------------

■PathとTextを持ったクラスを作成
public class Data
{
    public string Path { get; set; }
    public string Text { get; set; }
}

■Dataクラスのコレクションを作成
public partial class Window1 : Window
{
    public Window1()
    {
        InitializeComponent();

        List<Data> source = new List<Data>()
        {
            new Data() { Path="", Text="Text1"},
            new Data() { Path="", Text="Text2"},
            new Data() { Path="", Text="Text3"},
            new Data() { Path="", Text="Text4"},
            new Data() { Path="", Text="Text5"},
            new Data() { Path="", Text="Text6"},
            new Data() { Path="", Text="Text7"},
            new Data() { Path="", Text="Text8"},
            new Data() { Path="", Text="Text9"}
        };

        this.DataContext = source;
    }
}

■ItemsControlとUniformGridを使用して定型的なUIを作成
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ItemsControl ItemsSource="{Binding}">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <UniformGrid Rows="3" Columns="3" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical" Margin="5">
                        <Image Source="{Binding Path=Path}" Height="70" Width="70" />
                        <TextBlock TextWrapping="Wrap" HorizontalAlignment="Center" MaxWidth="90" FontSize="10" Text="{Binding Path=Text}" />
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</Window>

マスが9マス固定という前提です。9マス以上のデータがある場合は切り捨てられます。
もちろんUniformGridのRows・Columnsの指定で色々な表示が出来ます。
スマートか分かりませんが、こんな感じはどうでしょうか?

引用返信 編集キー/
■40043 / inTopicNo.3)  Re[2]: WPF 改善方法
□投稿者/ NICO (2回)-(2009/08/19(Wed) 17:30:07)
No40010 (kazuto さん) に返信

kazuto様

ご返信ありがとうございました。
Grid構成を記載するのを忘れていました。申し訳ありません。
推測されましたとおり、3×3のGrid構成で認識あっております。

上記のソースコードで実装できました!かなりコード量も減って感激してます!!

さらに、ご質問してもよろしいでしょうか?
ItemsControl のItemsSourceはList<Data>型(?)でなければいけないでしょうか?
"Data"クラスではなく、"Window1"クラス内で構造体みたいな形でもつこともできますでしょうか?その
その場合どのようにコーディングしたら実現できますでしょうか?

質問だらけでも申し訳ありません。。
どうぞよろしくお願いいたしますm(__)m

引用返信 編集キー/
■40046 / inTopicNo.4)  Re[3]: WPF 改善方法
□投稿者/ 倉田 有大 (701回)-(2009/08/19(Wed) 18:05:04)
> さらに、ご質問してもよろしいでしょうか?
> ItemsControl のItemsSourceはList<Data>型(?)でなければいけないでしょうか?
> "Data"クラスではなく、"Window1"クラス内で構造体みたいな形でもつこともできますでしょうか?その
> その場合どのようにコーディングしたら実現できますでしょうか?
>
> 質問だらけでも申し訳ありません。。
> どうぞよろしくお願いいたしますm(__)m


質問内容がかわっているので、別スレたてたほうがいいっすー

>ItemsControl のItemsSourceはList<Data>型(?)でなければいけないでしょうか?

ちゃいまっせ、それだと、汎用性が低すぎます。
IEnumerable を実装していればいいんじゃないかな。
引用返信 編集キー/
■40047 / inTopicNo.5)  Re[4]: WPF 改善方法
□投稿者/ kazuto (14回)-(2009/08/19(Wed) 18:20:54)
kazuto さんの Web サイト
2009/08/20(Thu) 00:43:12 編集(投稿者)
2009/08/20(Thu) 00:42:14 編集(投稿者)
2009/08/20(Thu) 00:40:34 編集(投稿者)

<pre><pre>ItemsControlに設定するデータソースはList<T>型である必要はありません。サンプルとして使用しただけです。

ItemsControlはデータコレクションを表示する為に使用するコントロールです。
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.itemscontrol.aspx

ですので、ItemsSourceに設定するオブジェクトはコレクションで有る必要があります。
もう少し言うと、IEnumerableを実装しているオブジェクトであれば使用する事が出来ます。
配列(Array)もIEnumerableを実装していますので、このようなデータコレクションでもOKです。

Data[] source = new Data[]
{
new Data() { Path = "", Text = "Text1"},
new Data() { Path = "", Text = "Text2"}
};

>"Data"クラスではなく、"Window1"クラス内で構造体みたいな形でもつこともできますでしょうか?
クラスではなく構造体を使用する詳細が分かりませんが、コレクションのデータ型は構造体でも大丈夫です。
また、Window1クラス内で定義しているクラスや構造体でも、もちろん大丈夫です。

IEnumerableを実装していればOKとは言いましたが、一応注意点を。
コレクションデータの一覧表示のみでしたら問題ないのですが、ItemsControlやそれを継承しているコントロールを使用する場合、
データバインディング後にそのコレクションデータに変更を加えるようなシチュエーションがあるのであればObservableCollection<T>を使用する必要があります。
コレクションデータに対しての変更がItemsControl等に反映されない為です。

ItemsControl.ItemsSource
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.itemscontrol.itemssource.aspx
バインディングソースの概要
http://msdn.microsoft.com/ja-jp/library/ms743643.aspx

こちらを一読されると良くわかると思います。
</pre></pre>
引用返信 編集キー/
■40093 / inTopicNo.6)  Re[5]: WPF 改善方法
□投稿者/ NICO (4回)-(2009/08/20(Thu) 11:59:36)
倉田 有大様 kazuto様

アドバイスありがとうございました。
データ情報は、構造体で管理し、構造体の配列でBindingするようにしました。

データ変更もできるようにしたかったので、ObservableCollection<T>を使用してみましたが、
書き換えでエラーとなってしまたので。。。(参照:★)

エラー 1 変数ではないため、'System.Collections.ObjectModel.Collection<View.Controller.ViewController.Data>.this[int]' の戻り値を変更できません。

--コード--
private ObservableCollection<Data> source = new ObservableCollection<Data>();
public ObservableCollection<Data> Source { get { return source ; } set { source = value; OnPropertyChanged("Source"); } }

public struct Data
{
 public string path;
public string text;

public string Path { get { return path; } }
public string Text { get { return text; } set { text = value; } }//OnPropertyChanged("Text"); } }
}

--★--
//イベント発生での処理
Source [0].Text = "xxx";

--------------------------------------------------------------------------------------------------

とりあえず、構造体の配列で、Get/Setの実装ができましたので、クローズいたします。

迅速、かつ丁寧な回答をいただけて、本当に助かりました。
また質問させていただくこともあるかもしれませんが、その際は、またどうぞよろしくお願いいたします。

ありがとうございました。


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -