uWat
uWat

Reputation: 147

Binding property of item from ItemsControl to value outside of ItemsSource?

I have an ItemsControl and I have a list of people. Each element in the list of people contains the person's name and nothing else. In the c# code, I set testItemsControl.ItemsSource to an observable collection that contain the name of each person. Company is defined in the code-behind. The following xaml code correctly finds the Name, but of course doesn't find the Company.

    <ItemsControl x:Name="testItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding Company}"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

How can I correctly bind the Company?

Upvotes: 1

Views: 2102

Answers (3)

rajnikant rajwadi
rajnikant rajwadi

Reputation: 36

You have to use RelativeSource binding.

Code behind.

public partial class Window3 : Window
{
    public Window3()
    {
        InitializeComponent();
        this.DataContext = this;
        BuildData();
        Company = "XYZ";
        testItemsControl.ItemsSource = Persons;
    }

    private void BuildData()
    {
        Persons.Add(new Person() { Name = "R1" });
        Persons.Add(new Person() { Name = "R2" });
        Persons.Add(new Person() { Name = "R3" });
    }

    public string Company { get; set; }

    private ObservableCollection<Person> _persons = new ObservableCollection<Person>();

    public ObservableCollection<Person> Persons
    {
        get { return _persons; }
        set { _persons = value; }
    }
}

XAML Code

<ItemsControl x:Name="testItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding Name}" Margin="5"/>
                    <TextBlock Text="{Binding Company, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Margin="5" />

                </StackPanel>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

Thanks, Rajnikant

Upvotes: 1

hkon
hkon

Reputation: 1045

Create a class to hold both Name and Company, compose your list with objects of your newly created type and set that as itemssource.

internal class Worker 
{
    public string Name { get; set; }
    public string Company { get; set; }
}

Upvotes: 0

Mikl&#243;s Balogh
Mikl&#243;s Balogh

Reputation: 2202

Each DataTemplate you defined uses an object from the ItemsControl.ItemsSource as DataContext. In your case its a person class.

So inside the DataTemplate it is looking for the Contents Name and Company property. In this case Person.Name, Person.Company.

If you want to find the Company you can add a company property to person class, or set the path of the binding to find the company property. The latter depends on where you defined the company property relative to the itemsSource

Upvotes: 0

Related Questions