TabControl which is bound to an ObservableCollection MVVM - wpf

I am currently working on a project using MVVM pattern and can't find anywhere a solution how to bind an ObservableCollection to a TabControl which has a template for an item of it.
For example, this is where I got so far:
<TabControl ItemsSource="{Binding ConnStringBufferOC}">
<TabControl.ItemTemplate>
<DataTemplate>
<Grid>
<TextBox Text="{Binding Username}"/>
<!-- Controls here -->
</Grid>
</DataTemplate>
</TabContro.ItemTemplate>
</TabControl>
This however only partialy works. It creates controls in the tab header area instead of the tab content area. I would want to bind each item to a new tab which has a header of a bound source from OC, for example:
Header="{Binding Name}"
And in the content area of each tab I would like to have controls, which have contents bound from the ObservableCollection in this example ConnStringBufferOC. So every tab has same controls only content bound to the controls is different.

You need to specify ContentTemplate for tab content and ItemTemplate for tab header
<TabControl ItemsSource="{Binding ConnStringBufferOC}">
<TabControl.ContentTemplate>
<DataTemplate>
<Grid>
<TextBox Text="{Binding Username}"/>
<!-- Controls here -->
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>

Related

How to bind multiple ViewModels into Expanders using Caliburn.Micro?

I have a XAML view that should hold instances of other views and those views should be displayed in a list, each contained in its own Expander. I'm using Caliburn.Micro and MEF to set all the components up.
The ItemsControl itself works just fine (shows the content of the view correctly):
<ItemsControl ItemsSource="{Binding CursorTools}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
But when I set the ItemsControl's DataTemplate to be an Expander, the Caliburn no longer "finds" the view for the viewmodel (so the expander is empty):
<ItemsControl ItemsSource="{Binding CursorTools}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--<ContentControl cal:View.Model="{Binding}" />-->
<Expander Header="{Binding Path=Title}">
<Expander.ContentTemplate>
<DataTemplate>
<ContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</Expander.ContentTemplate>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The problem is that I will have many items and their content will be large enough to fill the screen, so how can I get the Expander to set its content properly?
Expander is actually a ContentControl so this should work:
<Expander Header="{Binding Path=Title}" cal:View.Model="{Binding}" />

WPF DataTemplate Tooltip not displaying properly

I have a couple Comboboxes which use a DataTemplate and I am not able to set a Tooltip inside the DataTemplate to display. The DataTemplate utilizes a Textblock with a couple of <Run>'s. The Textblock inside the DataTemplate displays the data data properly except for the Tooltip (nothing pops up).
If I add the Tooltip directly to the Combobox it works but I do not want to do this because I would have to add the Tooltip to each Combobox that uses that DataTemplate.
Here is my ComboBox code
<ComboBox ItemsSource="{Binding Path=Items}"
SelectedItem="{Binding Path=HeaderRecord.Item}"
ItemTemplate="{StaticResource ItemTemplate}" />
Here is my Data Template
<DataTemplate x:Key="ItemTemplate" DataType="models:Item">
<TextBlock TextTrimming="CharacterEllipsis"
TextWrapping="NoWrap"
ToolTip="{Binding Path=Description, Mode=OneWay}">
<Run Text="{Binding Path=ItemNumber, Mode=OneWay}" />
<Run Text=": " />
<Run Text="{Binding Path=Description, Mode=OneWay}" />
</TextBlock>
</DataTemplate>

Bind textbox list inside listbox in wpf

I have to make listbox with textbox in it... and it has to be dynamic. I have observable collection in code behind and I want to bind that for listbox. I want dynamic listbox and this list should have editable textbox in it. So, basically I want to bind multiplr textbox from listbox. Any help would be appreciated
<ListBox HorizontalAlignment="Left" Name="ListTwo" Height="100" Margin="286.769,165.499,0,0" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Source=obs}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="TextBoxList"></TextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
By doing this, I have number of textbox same as items in observable collection but textbox's text is not set up.
If the items in your ObservableCollection are just plain strings, then you can data bind to the whole string value like this:
<ListBox Name="ListTwo" ItemsSource="{Binding Source=obs}" ... >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="TextBoxList" Text="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
From the Binding.Path Property page on MSDN:
Optionally, a period (.) path can be used to bind to the current source. For example, Text="{Binding}" is equivalent to Text="{Binding Path=.}".
Note that if you had some objects with properties in the collection, then #nit's answer would have been correct as you would need to reference the relevant property name:
<ListBox Name="ListTwo" ItemsSource="{Binding Source=obs}" ... >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Name="TextBoxList" Text="{Binding PropertyName}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You will have to Bind your textbox to the property in your class of which observable collection you have bound
<ListBox HorizontalAlignment="Left" Name="ListTwo" Height="100" Margin="286.769,165.499,0,0" VerticalAlignment="Top" Width="100" ItemsSource="{Binding Source=obs}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBox Binding="{Binding PROPERTYINCLASS}"></TextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

TabItem templates

I have a tab control defined as this:
<TabControl Grid.Row="1" ItemsSource="{Binding Path=Documents}">
<TabControl.ItemTemplate>
<DataTemplate>
<TabItem>
<Button Content="Test button"/>
</TabItem>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
I know that the Documents collection in the ViewModel is updated properly since I can see an empty tab header when I run my application, thus tab items are being created by the control. But for some reason there is no button in the tab item. Any ideas why this is happening?
Remove TabItem from your DataTemplate as at the moment you put TabItem within TabItem.
<TabControl Grid.Row="1" ItemsSource="{Binding Path=Documents}">
<TabControl.ItemTemplate>
<DataTemplate>
<Button Content="Test button"/>
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
also if you want to your Button to appear in Content part and not in the Header then instead of ItemTemplate use ContentTemplate

Display list of usercontrols within itemtemplate next to other controls

I would like to display a list of usercontrols binded to a listbox
next to each usercontrol there should be a button
<ListBox ItemsSource="{Binding usercontrollist}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<!--usercontrol of the current binded items-->
<Button Content="x" HorizontalAlignment="Right"></Button>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can i do this in xaml code
Assuming usercontrollist is a collection of UserControl, then you should be able to do this:
<ContentControl Content="{Binding}" />

Resources