Can one bind a combobox Itemssource from a datatemplate of a ItemsControl

限于喜欢 提交于 2019-12-20 05:31:59

问题


Given ComboBox in the ItemsControl will have different items which is based on the DataContext of the item (not of the ItemsControl). Can it be done? And how? Preferably from code behind.

I have the following DataModel:

class Tester
{
    public Tester(string name, string surname)
    {
        Name = name;
        Surname = surname;
    }

    public string Name { get; set; }
    public string Surname { get; set; }
    public override string ToString()
    {
        return Name + " " + Surname;
    }
}

class TheT
{
    public ObservableCollection<Tester> TesterObject;

    public TheT()
    {
        TesterObject = new ObservableCollection<Tester>();
    }

    public string myDisplayName { get { return "test"; } }

    public void Add(Collection<Tester> col)
    {
        TesterObject.Clear();
        foreach (Tester t in col) { TesterObject.Add(t); }
    }
}

In Window code I have:

ObservableCollection<TheT> myDataV ;
Public MainWindow()
{
    InitializeComponent();

    ObservableCollection<Tester> Tester1 = new ObservableCollection<Tester>();
    Tester1.Add(new Tester("Sunny", "Jenkins"));
    Tester1.Add(new Tester("Pieter", "Pan"));

    ObservableCollection<Tester> Tester2 = new ObservableCollection<Tester>();
    Tester2.Add(new Tester("Jack", "Sanders"));
    Tester2.Add(new Tester("Bill", "Trump"));

    myDataV = new ObservableCollection<TheT>();
    myDataV.Add(new TheT(Tester1));
    myDataV.Add(new TheT(Tester2));

    IControl.ItemsSource = myDataV;
    IControl.ItemTemplate = TestingDT;
}

IControl being an ItemsControl set up in XAML:

<ItemsControl x:Name="IControl" Margin="53,375,81,63">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

And DataTemplate that I have tried all kinds of ways. But still do not get items to show like below:

// the DataTemplate
private DataTemplate TestingDT
{
    get
    {
        DataTemplate DFT = new DataTemplate();
        DFT.DataType = typeof(TheT);

        FrameworkElementFactory Item = new FrameworkElementFactory(typeof(ComboBox));

        Binding B = new Binding("TesterObject")
        {
            Source = this
        };

        Item.SetBinding(ComboBox.ItemsSourceProperty, B);
        //Item.SetValue(ComboBox.DisplayMemberPathProperty, "Name");

        DFT.VisualTree = Item;
        return DFT;
    }
}

回答1:


with this little changes you should get your expected result

public class Tester {
  public Tester(string name, string surname) {
    Name = name;
    Surname = surname;
  }

  public string Name { get; set; }

  public string Surname { get; set; }

  public override string ToString() {
    return Name + " " + Surname;
  }
}

public class TheT : DependencyObject {
  public static readonly DependencyProperty TesterObjectProperty =
    DependencyProperty.Register("TesterObject", typeof(ObservableCollection<Tester>), typeof(TheT),
                                new FrameworkPropertyMetadata());

  public ObservableCollection<Tester> TesterObject {
    get { return (ObservableCollection<Tester>)GetValue(TesterObjectProperty); }
    set { SetValue(TesterObjectProperty, value); }
  }

  public TheT(Collection<Tester> col) {
    TesterObject = new ObservableCollection<Tester>();
    foreach (Tester t in col) { TesterObject.Add(t); }
  }

  public void Add(Collection<Tester> col) {
    TesterObject.Clear();
    foreach (Tester t in col) { TesterObject.Add(t); }
  }
}

public Window1()
{
  InitializeComponent();

  ObservableCollection<Tester> Tester1 = new ObservableCollection<Tester>();
  Tester1.Add(new Tester("Sunny", "Jenkins"));
  Tester1.Add(new Tester("Pieter", "Pan"));

  ObservableCollection<Tester> Tester2 = new ObservableCollection<Tester>();
  Tester2.Add(new Tester("Jack", "Sanders"));
  Tester2.Add(new Tester("Bill", "Trump"));

  var myDataV = new ObservableCollection<TheT>();
  myDataV.Add(new TheT(Tester1));
  myDataV.Add(new TheT(Tester2));

  IControl.ItemsSource = myDataV;
}

xaml

<Window x:Class="stackoverflow.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:stackoverflow"
        Title="stackoverflow"
        Height="300"
        Width="300">

  <Grid>

    <ItemsControl x:Name="IControl" Margin="10">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <VirtualizingStackPanel Orientation="Horizontal"/>
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
      <ItemsControl.ItemTemplate>
        <DataTemplate DataType="{x:Type local:TheT}">
          <ComboBox ItemsSource="{Binding TesterObject}"
                    MinWidth="80"
                    DisplayMemberPath="Name" />
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>

  </Grid>

</Window>

hope that helps



来源:https://stackoverflow.com/questions/17555458/can-one-bind-a-combobox-itemssource-from-a-datatemplate-of-a-itemscontrol

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!