0
votes

I´m trying to bind a ListBox to a ObservableCollection. I wan´t to bind the Text Properties of the ListBox entrys and the Background of the ListBox entrys.

The ListBox is defined in an loaded loose xaml file:

<TextBox Margin="0,5,5,5" Text="{Binding Path=TB9P}" Background="LightBlue" Name="DetailsviewTB9" Height="20">
        <TextBox.ToolTip>
            <StackPanel>
                <Label FontWeight="Bold" Background="Blue" Foreground="White">Daten</Label>
                <ListBox ItemsSource="{Binding Source={StaticResource res_LB1P}}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                                <TextBlock Text="{Binding Path=StringP}" Background="{Binding Path=SelectedItemP, Converter={StaticResource c_SelectedItemToBackgroundConverter}}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </TextBox.ToolTip>
    </TextBox>

The DataContext is set on class DetailsViewText

public class LBEntry
{
    bool DetailsViewLBSelectedItem = true;

    string DetailsViewLB = "test";

    public LBEntry(bool selcected, string str)
    {
        DetailsViewLB = str;
        DetailsViewLBSelectedItem = selcected;
    }

    public bool SelectedItemP
    {
        get { return DetailsViewLBSelectedItem; }
        set { DetailsViewLBSelectedItem = value; }
    }

    public string StringP
    {
        get { return DetailsViewLB; }
        set { DetailsViewLB = value; }
    }
}

public class LBEntrysCollection : System.Collections.ObjectModel.ObservableCollection<LBEntry>
{
    //
}

public class DetailsViewText
{
    string[] DetailsViewTB1_Text = new string[20];
    bool[] fDetailsViewCB = new bool[20];


    LBEntrysCollection[] LBEntrys = new LBEntrysCollection[]{
            new LBEntrysCollection{ new LBEntry(false, "test"), new LBEntry(true, "test") },
            new LBEntrysCollection{ new LBEntry(true, "test") },
            new LBEntrysCollection{ new LBEntry(false, "test") },
            new LBEntrysCollection{ new LBEntry(false, "test") },
            new LBEntrysCollection{ new LBEntry(false, "test") }
    };

    public LBEntrysCollection LB1P
    {
        get { return LBEntrys[0]; }
        set { LBEntrys[0] = value; }
    }

    public string TB9P
    {
        get { return DetailsViewTB1_Text[8]; }
        set { DetailsViewTB1_Text[8] = value; }
    }

    ...
    }

The resource res_LB1P is set in the mainWindow constructor:

// Resources
        this.Resources.Add("res_LB1P", detailsViewFrameHandling.DetailsViewTextP.LB1P);

Basicly I just want to bind the ListBox to a LBEntrysCollection with SelectedItemP as switch for the background Color and StringP as the Text Property. But I need the DataContext on DetailsViewText for other Propertys.

I´m getting an Exception when the xaml File is loading the StaticResource res_LB1P. How do I have to set my Binding on ListBox and TextBlock to get it right?

EDIT: With this

<ListBox ItemsSource="{Binding Path=LB1P}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                                <TextBlock Text="{Binding Path=LB1P.StringP}" />
                    </DataTemplate>
                </ListBox.ItemTemplate>
                </ListBox>

Items are added, but there is no Text shown in the TextBox


Now I´m really confused. It does work like this:

<ListBox ItemsSource="{Binding Path=LB1P}">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                                <TextBlock Text="{Binding Path=StringP}" Background="{Binding Path=SelectedItemBrushP}"/>
                    </DataTemplate>
                </ListBox.ItemTemplate>
                </ListBox>

Simple enough, but I thought i had tried this before and it didn´t work...

Is it possible, that if one Binding does fail (the Background Binding) the other Binding (Text Property) does also not work?

2

2 Answers

0
votes

I have always considered the ViewModel (the object the DataContext points to) to be just that: a Model of the View.

So to solve this, you need either one object that will be the ViewModel because there is only one DataContext property or you will need to add an extra DataContext-like property.

The first option (one ViewModel) can be realized by creating a new class that contains both the ObservableCollection and the DetailsViewText:

class ComposedViewModel: INotifyPropertyChanged
{
    public LBEntrysCollection LBEntries
    {
         get { ... }
         set { ... } 
    }

    public DetailsViewText Details
    {
        get { ... }
        set { ... }
    }
}

The second option (extra DataContext-like property) can be realized by sub-classing the ListBox and adding another property.

0
votes

Why not do this ?

<ListBox ItemsSource="{Binding ElementName=<TextBox's Name>, Path=DataContext">
            <ListBox.ItemTemplate>
                <DataTemplate>
                            <TextBlock Text="{Binding Path=StringP}" Background="{Binding Path=SelectedItemP, Converter={StaticResource c_SelectedItemToBackgroundConverter}}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>
            </ListBox>

Correct me if I'm wrong with understanding your question. You want to bind the listbox's itemssource to the textbox's datacontext?