none
ListViewのUserControlについて RRS feed

  • 質問

  • お世話になっております。

    ListView内にUserControlを配置した際に、うまく表示ができておりません。

    UserControlのComboBoxにNoをバインドしているのですが、そのNoが「1,2,3,4」と表示されて欲しいのが、「1,1,1,1」になってしまっています。

    UserControlと同じ物を直接ListViewに配置した際は上手く表示ができております。

    やりたいことは、ObserbalCollectionのリストを、ListViewなどで表示し、その中の要素としてComboBox風なUserControlを配置したいです。

    ListViewにはこだわりは無いので、この方法以外で上手くいくのでしたら、他の方法でも構いません。

    開発環境は VisualStudio 2015 Pro .NetFrameWork 4.6 です。

    どなたか、お助け下さい。

    以下コードです。

    MainWindow.xaml
    <Window x:Class="GridView_Test_Soft.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:GridView_Test_Soft"
            mc:Ignorable="d"
            Title="MainWindow" Height="Auto" Width="Auto">
        <Window.DataContext>
            <local:ViewModel/>
        </Window.DataContext>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="4*"/>
            </Grid.ColumnDefinitions>
    
            <local:MyUserControl DataContext="{Binding Parents[0].Children[0]}" Height="100" />
            <local:MyUserControl DataContext="{Binding Parents[0].Children[1]}" Height="100" Grid.Column="1"/>
            <local:MyUserControl DataContext="{Binding Parents[0].Children[2]}" Height="100" Grid.Column="2"/>
            <local:MyUserControl DataContext="{Binding Parents[0].Children[3]}" Height="100" Grid.Column="3"/>
            <ListView ItemsSource="{Binding Parents}" Grid.Column="4"  >
                <ListView.View>
                    <GridView>
                        <GridViewColumn x:Name="Child1_No"  Width="100" >
                            <GridViewColumnHeader Content="Child1_No" x:Name="Child1_No_Header"/>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <local:MyUserControl DataContext="{Binding Children[0]}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn x:Name="Child2_No"  Width="100" >
                            <GridViewColumnHeader Content="Child2_No" x:Name="Child2_No_Header"/>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <local:MyUserControl DataContext="{Binding Children[1]}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn x:Name="Child3_No"  Width="100" >
                            <GridViewColumnHeader Content="Child3_No" x:Name="Child3_No_Header"/>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <local:MyUserControl DataContext="{Binding Children[2]}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn x:Name="Child4_No"  Width="100" >
                            <GridViewColumnHeader Content="Child3_No" x:Name="Child4_No_Header"/>
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <local:MyUserControl DataContext="{Binding Children[3]}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn x:Name="Combo1"  Width="100" >
                            <GridViewColumnHeader Content="Combo1" />
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <ComboBox SelectedIndex="{Binding Children[3].No}"   >
                                        <ComboBoxItem Content="1" />
                                        <ComboBoxItem Content="2" />
                                        <ComboBoxItem Content="3" />
                                        <ComboBoxItem Content="4" />
                                        <ComboBoxItem Content="5" />
                                        <ComboBoxItem Content="6" />
                                        <ComboBoxItem Content="7" />
                                        <ComboBoxItem Content="8" />
                                        <ComboBoxItem Content="9" />
                                        <ComboBoxItem Content="10"/>
                                    </ComboBox>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
        </Grid>
    
    </Window>
    ViewModel
    
    using System.Collections.ObjectModel;
    
    namespace GridView_Test_Soft
    {
        class ViewModel : ViewModelBase
        {
            public ViewModel()
            {
                Parents = new ObservableCollection<Parent>();
                for(int i = 0; i < 10; i++)
                {
                    Parent My_Parent = new Parent();
                    Parents.Add(My_Parent);
                }
            }
    
            private ObservableCollection<Parent> _parents;
            public ObservableCollection<Parent> Parents
            {
                get
                {
                    return _parents;
                }
                set
                {
                    _parents = value;
                    NotifyPropertyChange("Parents");
                }
            }
        }
    }

    Parent.cs
    
    using System.Collections.ObjectModel;
    
    namespace GridView_Test_Soft
    {
        using System.Collections.ObjectModel;
    
        namespace GridView_Test_Soft
        {
            class Parent : ViewModelBase
            {
                public Parent()
                {
                    Children = new ObservableCollection<Child>();
                    for (int i = 0; i < 4; i++)
                    {
                        Child My_Child = new Child();
                        My_Child.No = i;
                        Children.Add(My_Child);
                    }
                }
                private ObservableCollection<Child> _children;
                public ObservableCollection<Child> Children
                {
                    get
                    {
                        return _children;
                    }
                    set
                    {
                        _children = value;
                        NotifyPropertyChange("Children");
                    }
                }
            }
    
            class Child : ViewModelBase
            {
    
                private int _no;
                public int No
                {
                    get
                    {
                        return _no;
                    }
                    set
                    {
                        _no = value;
                        NotifyPropertyChange("No");
                    }
                }
            }
        }
    
    }


    MyUserControl.xaml
    <UserControl x:Class="GridView_Test_Soft.MyUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:GridView_Test_Soft"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.DataContext>
            <local:Child/>
        </UserControl.DataContext>
        <Grid>
            <ComboBox SelectedIndex="{Binding No}" 
                      VerticalContentAlignment="Center"
                      HorizontalContentAlignment="Center">
                
                <ComboBoxItem Content="1" />
                <ComboBoxItem Content="2" />
                <ComboBoxItem Content="3" />
                <ComboBoxItem Content="4" />
                <ComboBoxItem Content="5" />
                <ComboBoxItem Content="6" />
                <ComboBoxItem Content="7" />
                <ComboBoxItem Content="8" />
                <ComboBoxItem Content="9" />
                <ComboBoxItem Content="10" />
            </ComboBox>   
        </Grid>
    </UserControl>


    • 編集済み y_nakata 2016年1月12日 7:46
    2016年1月12日 7:41

回答

  • こんにちは。

    UserControlでDataContextを直接指定していますが親からDataContextを渡されるので不要ではないですか。

    <UserControl x:Class="GridView_Test_Soft.MyUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:GridView_Test_Soft"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <!--<UserControl.DataContext>
            <local:Child/>
        </UserControl.DataContext>-->
        <Grid>
            <ComboBox SelectedIndex="{Binding No}" 
                      VerticalContentAlignment="Center"
                      HorizontalContentAlignment="Center">

    • 回答としてマーク y_nakata 2016年1月14日 3:02
    2016年1月12日 8:21
    モデレータ

すべての返信

  • こんにちは。

    UserControlでDataContextを直接指定していますが親からDataContextを渡されるので不要ではないですか。

    <UserControl x:Class="GridView_Test_Soft.MyUserControl"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:GridView_Test_Soft"
                 mc:Ignorable="d" 
                 d:DesignHeight="300" d:DesignWidth="300">
        <!--<UserControl.DataContext>
            <local:Child/>
        </UserControl.DataContext>-->
        <Grid>
            <ComboBox SelectedIndex="{Binding No}" 
                      VerticalContentAlignment="Center"
                      HorizontalContentAlignment="Center">

    • 回答としてマーク y_nakata 2016年1月14日 3:02
    2016年1月12日 8:21
    モデレータ
  • Tak1waさん

    返信ありがとうございます。

    UserControl の DataContext をコメントアウトすれば問題なく動作いたしました。

    ありがとうございます。

    UserControl の DataContext は、プロパティ画面からデータバインドを作成する際に必要だったので記述していたのですが、

    UserControl を Grid に直接配置している方は上手く表示できていたのですが、ListView 内に配置している方との違いは何なのでしょうか?

    2016年1月12日 9:43
  • 以下のサイトの説明が分かりやすいでしょうか

    http://pieceofnostalgy.blogspot.jp/2012/04/wpf-datacontext.html

    2016年1月13日 1:40
  • UserControl を Grid に直接配置している方は上手く表示できていたのですが、ListView 内に配置している方との違いは何なのでしょうか?

    Gridに直接配置の時はわかりやすいので問題ないと思います。問題なのはListView内に配置された場合ですね。
    Visual Studio 2015に付属のライブプロパティエクスプローラーで見てみましたが、MyUserControlのインスタンス生成時にセットされるDataContextに変更がありませんでした。つまり、ListViewの中でMyUserControlのDataConTextにセットしているバインディングが無視されています。DataContextは正しくセットされているけれど、表示が更新されていないということではなさそうです。
    詳しいことはわかりませんが、仕様として、ListViewItemなどのように動的に生成されるものに配置されているコントロールのDataContextの指定は無視されるのかもしれません。ただ、この理由もわかりませんが・・・
    この辺りの文書を探してみましたが、見つけることができませんでした。


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    2016年1月13日 5:28
    モデレータ
  • せれさん

    リンクのサイト、大変参考になりました。

    今回で言えば、Grid にDataContext を記述すればよかったのですね。

    ありがとうございます。

    trapemiyaさん

    返信ありがとうございます。

    まさか、無視されているとは。。

    回避策が分かったので今後気を付けます。

    ありがとうございます。

    2016年1月14日 3:02