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

わんくま同盟

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

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

ツリー一括表示

WPF、ItemsControlでConverterに渡す値 /かい (18/02/10(Sat) 02:37) #86539
Re[1]: WPF、ItemsControlでConverterに渡す値 /Hongliang (18/02/10(Sat) 06:32) #86540
  └ Re[2]: WPF、ItemsControlでConverterに渡す値 /かい (18/02/10(Sat) 16:27) #86542
    └ Re[3]: WPF、ItemsControlでConverterに渡す値 /Hongliang (18/02/10(Sat) 19:28) #86544
      └ Re[4]: WPF、ItemsControlでConverterに渡す値 /かい (18/02/11(Sun) 20:31) #86546 解決済み


親記事 / ▼[ 86540 ]
■86539 / 親階層)  WPF、ItemsControlでConverterに渡す値
□投稿者/ かい (16回)-(2018/02/10(Sat) 02:37:54)

分類:[.NET 全般] 

お世話になっています。
C#WPFの想定です。

ItemsControlのItemsSourceに以下の構造のクラスを指定したとして、
Converterに渡すものをクラスから、クラスのプロパティの一部に絞ることは可能でしょうか。
よろしければご指導下さい。

-構造-
public class EntityViewTitleHierarchy
{
    #region Field
    /// <summary>
    /// Title
    /// </summary>
    public string Title { get; set; }
    /// <summary>
    /// CommandParameter用
    /// </summary>
    public NameTitle NameTitle { get; set; }
    #endregion
}
※NameTitleはenum型です。

-希望する処理のイメージ-
<ItemsControl ItemsSource="{Binding Path=TitleList}"
          Grid.Row="0" Grid.Column="0"
          AlternationCount="{x:Static mscorlib:Int32.MaxValue}"
          >
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Resources>
                    <convert:ArrayConverterForTeleport x:Key="ArrayConverterForTeleport"/>
                </TextBlock.Resources>
                <TextBlock.InputBindings>
                    <MouseBinding Command="{Binding RelativeSource={RelativeSource FindAncestor, 
                                                    AncestorType={x:Type Window}}, f
                                                    Path=DataContext.CommandDispatching}" 
                                  MouseAction="LeftClick">
                        <MouseBinding.CommandParameter>
                            <MultiBinding Converter="{StaticResource ArrayConverterForTeleport}">

                                <!--以下のように、プロパティだけ渡してやりたいが、効かない-->
                                <Binding RelativeSource="{RelativeSource FindAncestor,                         
                                    AncestorType={x:Type ItemsControl}}"
                                                 Path="DataContext.NameTitle"/>


                                <Binding RelativeSource="{RelativeSource Mode=TemplatedParent}" 
                                                 Path="(ItemsControl.AlternationIndex)"/>
                            </MultiBinding>
                        </MouseBinding.CommandParameter>
                    </MouseBinding>
                </TextBlock.InputBindings>
                <Run Text="&#9654;"></Run>
                <Run Text="{Binding Path=Title}"></Run>
            </TextBlock>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>


[ □ Tree ] 返信 編集キー/

▲[ 86539 ] / ▼[ 86542 ]
■86540 / 1階層)  Re[1]: WPF、ItemsControlでConverterに渡す値
□投稿者/ Hongliang (612回)-(2018/02/10(Sat) 06:32:56)
EntityViewTitleHierarchyというクラスだけ書かれても。
ItemsControl::ItemsSourceに渡しているTitleListというのはどこに。

とりあえず、
class VM {
  public List<EntityViewTitleHierarchy> TitleList { get; set; }
}
がItemsControl::DataContextにあると仮定します。

> <Binding RelativeSource="{RelativeSource FindAncestor,                         
>               AncestorType={x:Type ItemsControl}}"
>               Path="DataContext.NameTitle"/>

このバインディングはソースにItemsControlを、パスにDataContext.NameTitleを指定しています。
ItemsControl::DataContextは上述のVMクラスなので、VMが持っているNameTitleになります。
class VM {
  public List<EntityViewTitleHierarchy> TitleList { get; set; }
  public NameTitle NameTitle { get; set; }
}
こうですね。

// ItemsSourceの個々のアイテムがこのクラスで、
// ここでこのプロパティにバインドしたい、といった説明がないと
// 仮定の現状を説明するぐらいしかできません。

[ 親 86539 / □ Tree ] 返信 編集キー/

▲[ 86540 ] / ▼[ 86544 ]
■86542 / 2階層)  Re[2]: WPF、ItemsControlでConverterに渡す値
□投稿者/ かい (17回)-(2018/02/10(Sat) 16:27:17)
Hongliang さん

返信ありがとうございます。
指摘の通りでした。記載漏れがあった点、お詫びします。

重ねてもう一点お詫びします。
提示したxamlですが、コメントのある個所を以下のように修正することで、望み通りになりました。

<Binding RelativeSource="{RelativeSource FindAncestor,
AncestorType={x:Type TextBlock}}"
Path="DataContext.NameTitle"/>

祖先検索でItemsControlを指定していた為、TitleListはあるが、TitleListのNameTitleが見つからずunsetとなった模様です。


以上の非礼のうえで不躾ですが、もし以下の点をご存じでしたら教えて頂けるでしょうか。


Viewをnewし、DataContextにnewしたViewModelを格納後、
View.Show()を実行します。

その時、xamlに記載された全てのconverterが実行されるのですが、
これを指定のactionを実行する時以外は実行されないように、挙動を抑制することは出来るでしょうか。
(提示したxamlで言うと、LeftClick押下時以外は実行されないようにしたい)

重ね重ね失礼しました。


[ 親 86539 / □ Tree ] 返信 編集キー/

▲[ 86542 ] / ▼[ 86546 ]
■86544 / 3階層)  Re[3]: WPF、ItemsControlでConverterに渡す値
□投稿者/ Hongliang (613回)-(2018/02/10(Sat) 19:28:40)
> <Binding RelativeSource="{RelativeSource FindAncestor,
> AncestorType={x:Type TextBlock}}"
> Path="DataContext.NameTitle"/>
そもそもこの時点でのデータコンテキストはTextBlockにあるので、わざわざRelativeSourceなど記述しなくても、
<Binding Path="NameTitle"/>
だけで十分ですよ。
<Run Text="{Binding Path=Title}"></Run>
の方でわざわざRelativeSourceを書かないのと同じ。
ちなみに、Bindigマークアップ拡張では、パラメータ名を持たない第1引数はPathを指すので、{Binding Title}だけでもいいです。

> その時、xamlに記載された全てのconverterが実行されるのですが、
> これを指定のactionを実行する時以外は実行されないように、挙動を抑制することは出来るでしょうか。
> (提示したxamlで言うと、LeftClick押下時以外は実行されないようにしたい)
こっちは無理じゃないですかねー。
なにか現状の動作で不具合がありますか?
[ 親 86539 / □ Tree ] 返信 編集キー/

▲[ 86544 ] / 返信無し
■86546 / 4階層)  Re[4]: WPF、ItemsControlでConverterに渡す値
□投稿者/ かい (19回)-(2018/02/11(Sun) 20:31:39)
> そもそもこの時点でのデータコンテキストはTextBlockにあるので、わざわざRelativeSourceなど記述しなくても、
> <Binding Path="NameTitle"/>
> だけで十分ですよ。
> <Run Text="{Binding Path=Title}"></Run>
> の方でわざわざRelativeSourceを書かないのと同じ。
> ちなみに、Bindigマークアップ拡張では、パラメータ名を持たない第1引数はPathを指すので、{Binding Title}だけでもいいです。

知りませんでした。教えて下さってありがとうございます。

> こっちは無理じゃないですかねー。
> なにか現状の動作で不具合がありますか?

提示したxamlで値がunsetとなる場合があるので伺ってみました。
まだ検証していないので原因は不明ですが、
AlternationIndexが0、
続けてAlternationIndexが0かつNameTitleが格納されている引数を持つconverterが実行されているので、
ItemsControlそのものがインスタンス化する時にもconverterが走るのだろうと思っています。

いずれにせよ難しいことはわかりましたので、converter内にチェック機構を入れることで対応します。

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


解決済み
[ 親 86539 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -