質問者
ContentTemplateを指定したときと指定していないときでBindingの挙動が変わる

質問
-
コレクションをIsSynchronizedWithCurrentItemをTrueに設定したListBoxにバインドした状態で、同じコレクションをContentControlのContentにバインドしたときの挙動に以下のような違いがあります。
- ContentTemplateを指定していないとき
コレクションのToStringをした結果が表示される - ContentTemplateを指定したとき
ListBoxで現在選択されている項目が表示される
この挙動を再現するプログラムは以下のようになります。<Window x:Class="WpfTemplate.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfTemplate="clr-namespace:WpfTemplate" Title="Window1" Height="300" Width="300"> <Window.Resources> <DataTemplate x:Key="personViewTemplate" DataType="{x:Type WpfTemplate:Person}"> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Name}"/> <TextBlock Text="さん " /> <TextBlock Text="{Binding Age}"/> <TextBlock Text="歳" /> </StackPanel> </DataTemplate> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <ListBox Grid.Row="0" ItemsSource="{Binding}" ItemTemplate="{StaticResource personViewTemplate}" IsSynchronizedWithCurrentItem="True"/> <ContentControl Grid.Row="1" Content="{Binding}" ContentTemplate="{StaticResource personViewTemplate}"/> </Grid> </Window>
using System.Linq; using System.Windows; namespace WpfTemplate { public partial class Window1 : Window { public Window1() { InitializeComponent(); var people = from age in Enumerable.Range(10, 10) select new Person { Name = "太郎" + age, Age = age }; this.DataContext = people; } } public class Person { public string Name { get; set; } public int Age { get; set; } } }
上記のコードでContentControlからContentTemplateを設定してるときの挙動とContentTemplateを指定していないときの挙動の違いです。ContentControlのBindingのPathに/を指定すると、挙動の差異はなくなるのでContentTemplateを指定した場合は暗黙的にPathに/が設定されるような動きになっています。挙動が違うことは理解したのですが、この動きが仕様として明示してある箇所をMSDN内で見つけることができませんでした。どなたか、この挙動に関する情報を持っているかたがいたら教えてください。
かずき Blog:http://d.hatena.ne.jp/okazuki/ - ContentTemplateを指定していないとき
すべての返信
-
http://msdn.microsoft.com/ja-jp/library/system.windows.data.binding.path(v=VS.90).aspx
解説
ソースがコレクション ビューであるときは、現在の項目をスラッシュ (/) で指定できます。たとえば、Path=/ 句は、ビュー内の現在の項目へのバインディングを設定します。ソースがコレクションである場合、この構文は、既定のコレクション ビューの現在の項目を指定します。この説明でどうでしょうか?
えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2010/12 -
{Binding} の場合は {Binding .} とおなじです。
http://msdn.microsoft.com/ja-jp/library/system.windows.data.binding.path(v=VS.90).aspx
解説また、ピリオド (.) パスを使用して現在のソースにバインドすることもできます。たとえば、Text=”{Binding}” は Text=”{Binding Path=.}” と同じ意味です。
このため IEnumerable<Person> に対するコレクションビューをさします。
ContentTemplate="{StaticResource personViewTemplate}"/>
この分ではDataTemplateを示します。なのでコレクションビューの中身のPersonがDataTypeと一致するとわかるのだと思います。
えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2010/12 -
http://msdn.microsoft.com/ja-jp/library/aa970558.aspx
えムナウ@わんくま同盟 Microsoft MVP Visual Studio C# Since 2005/01-2010/12