bind item's children control in ItemsControl wpf - c#

i am binding an ItemsControl to a list, but in item template there is a control which is not binding by current dataSource, i want to bind it with another dataSource.
but i am stuck at accessing that control
my ItemsControl's dataTemplate is--->
<ItemsControl x:Name="ItemRequesterList" IsTabStop="False">
<ItemsControl.ItemTemplate>
<DataTemplate x:Name="ItemReqTemplate">
<StackPanel Margin="10,0,0,0">
<TextBlock Text="{Binding DisplayName}"></TextBlock>
<TextBlock Text="requested on"></TextBlock>
<TextBlock Text="{Binding}"></TextBlock> //<---this control, i
// want to bind with another dataSource
</StackPanel>
</DataTemplate>
so how can i access this control, which is lie in each item ?

You could bind the DataContext of that control to some static resource, for example:
<TextBlock Text="{Binding}" DataContext="{StaticResource myOtherContext}"></TextBlock>
See the following:
Silverlight - Setting DataContext in XAML rather than in constructor?

Related

Nesting databound controls inside a WPF TreeView

Trying to build a WPF TreeView control which can contain another data bound control inside it. Here's the XAML:
<TreeView temsSource="{Binding DocumentCategories}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding DocumentCategory1}">
<TextBlock FontWeight="Bold" Text="{Binding Description}"></TextBlock>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<ListView ItemsSource="{Binding Documents}">
<TextBlock FontWeight="Bold" Text="{Binding Name}"></TextBlock>
</ListView>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
The DocumentCategories data is recursive - each item in the list has a DocumentCategory1 collection of DocumentCategories which has its own DocumentCategory1 collection and so forth.
Without the ListView inside it, this works just fine. However, when you add the ListView the TreeView renders ok but when you try and open one of the nodes, the application crashes with the error:
Operation is not valid while ItemsSource is in use. Access and modify
elements with ItemsControl.ItemsSource instead
I'm not entirely sure which ItemsSource this is referring to - that of the TreeView or the ListView. I presume the latter, and that the problem is being caused by the fact that the binding isn't actually happening until after the node is opened.
I've tried changing both DocumentCateegories and Documents from List to an ObservableCollection, which seems to be a common fix for this error - but it still behaves the same.
Is it possible to have another databound control inside a TreeView, and if so, how?
There is the DataTemplate of the ListView missing.
Currently the following Element is interpreted as an actual ListView Element:
<TextBlock FontWeight="Bold" Text="{Binding Name}"></TextBlock>
And as you already bound the ListView's ItemSource the error occurs, when the view is trying to add the "TextBlock" as an item of the ListView.
Just change it to the following:
<ListView ItemsSource="{Binding Documents}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" Text="{Binding Name}"></TextBlock>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Unable to bind collection to ComboBox in silverlight

I've a ObservableCollection, when I want to display this ObservableCollection with CheckBox I am simply binding the contents to CheckBox but when I want to display the same collection by using ComboBox I am unable to do that. Any suggestions?
XAML: Display collection using CheckBox --WORKS
<ItemsControl ItemsSource="{Binding Synonyms}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--Display items in CheckBox-->
<CheckBox Content="{Binding Display}" Margin="10,0,0,0" /> // Display is the collection.
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Output:
XAML: Display collection using ComboBox --NOTHING OVER HERE
<ItemsControl ItemsSource="{Binding Synonyms}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Margin="0,5,0,0" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--Display items in ComboBox.-->
Approach - 1
<ComboBox>
<ComboBoxItem Content="{Binding Display}"/>
</ComboBox>
Approach - 2
<ComboBox ItemsSource="{Binding Path=Synonyms}" DisplayMemberPath="Display"/>
Approach - 3
<ComboBox >
<ComboBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Green" BorderThickness="1" Padding="5">
<TextBlock Text="{Binding Path=Display,StringFormat='Display: {0}'}" />
</Border>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Output:
I want to display items(one,two,three, etc.) inside oneComboBox with Select All option. I've tried several approaches but nothing. What am I missing here?
The checkbox is not designed to hold multiple items unlike the Combobox so implementing a system designed for the checkbox is not relevant for the combobox.
To solve your issue, remove the combobox from the ItemsControl and have it stand on its own:
<ComboBox ItemsSource="{Binding Synonyms}" DisplayMemberPath="Display"/>
Which tells the combobox to bind its ItemsSource to the data context which is unspecified, which is fine, so it then gets it's parent's data context. That process works its way up to each parent until it finds a bound data context (most likely the page's datacontext to a VM instance).
Assuming that the data context is valid at some point in the visual tree, it will bind to that instance and look for a property named Synonyms. From the Synonyms property it will use that as a list to display items.
To show (display) text in the combobox (instead defaulting to the item's ToString()) the combobox will show the string from the item's property Display.
Giving a list of items in one drop down.
The short answer, is you should use a ComboBox as the root element, not ItemsControl. CompboBox is just a specialized version of ItemsControl.
<ComboBox ItemsSource="{Binding Synonyms}" DisplayMemberPath="Display"/>
The longer answer.
ComboBox derives from ItemsControl, so you get all the features the base class, plus additional features.
ItemsControl (and its derived classes) provides a way of repeating a set of data in the UI. The DataTemplate is where you specify what UI you want for each "row" of data in the Synonyms source.
What you are doing is asking Silverlight to create a separate ComboBox for each underlying data row.
You can still use a DataTemplate within the ComboBox. Like this.
<ComboBox ItemsSource="{Binding Synonyms}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--Display items in CheckBox-->
<TextBox Text="{Binding Display}"
Margin="10,0,0,0"
FontWeight="Bold" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Hide last item in a ItemsControl

I've a ItemsControl that I bind to my viewmodel, but inside the datatemplate I also have an image. I want that image to be visible as long as it's not the last item in the list, then it should be hidden (it's an arrow that point down to the next control).
The xaml look like this:
<ItemsControl ItemsSource="{Binding PageContainers}" x:Name="Items">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<controls:DesignControl DataContext="{Binding}" MouseDown="UIElement_OnMouseDown" MouseUp="UIElement_OnMouseUp" MouseMove="UIElement_OnMouseMove"/>
<Image Source="/Resources/Images/arrow.png" Height="16" Width="16" Margin="0,10,0,0"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
So is there any easy to check if the Image/Stackpanel is last in the list? I guess I could subscribe to some event and do it in the code behind, but I guess it's cleaner if I could do it inside the xaml.
You're binding to PageContainers which I assume to be a collection. Can the type of that collection be extended to include an IsLast property?
If it can, you can bind the visibility to that.

How to create a DataTemplate with a StackPanel of a variable number of StackPanels

I am trying to create a DataTamplate which should contain a StackPanel with a certain number of StackPanels.
<DataTemplate x:Key="DataTemplate">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Rectangle Fill="Aqua" Margin="2" Height="100" Width="50" VerticalAlignment="Top" HorizontalAlignment="Left"/>
</StackPanel>
</StackPanel>
</DataTemplate>
The code snippet above is just for a better understanding of my desired result, as the elements in the imbricated StackPanel will be binded.
This generates the following error message:
VisualTree of ItemsPanelTemplate must be a single element.
Any alternatives that could work?
You should ItemsControl with ItemsSource bound to your source list. In ItemsControl.ItemsPanel you can set which panel you want to use for items. In your case you should use StackPanel with Orientation=Vertical as ItemsPanel. See first sample here. But vertical StackPanel is already default ItemsPanel so you can omit it.
Inner StackPanel should be specified as ItemTemplate in your ItemsControl.
Your XAML should look like this:
<ItemsControl ItemsSource="...">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- properties of your object should go here -->
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Silverlight: Access parent data context from DataTemplate?

I'm using Silverlight 4. I have an ItemsControl with a custom DataTemplate. From that DataTemplate, I would like to bind to something in the UserControl's DataContext - not the DataContext of a specific element in the items control. Is there a way to do this?
This should answer your question : Access parent DataContext from DataTemplate
<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content={Binding MyLevel2Property}
Command={Binding ElementName=level1Lister, Path=DataContext.MyLevel1Command}
CommandParameter={Binding MyLevel2Property}>
</Button>
<DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>

Categories