I want to bind a Count of ItemsSource of an ItemsControl in a TextBlock using WPF.
Have a Look into my tried Code
<Menu>
<MenuItem>
<MenuItem.Header>
<TextBlock Text="{Binding Path=(ItemsControl.ItemsSource.Item, RelativeSource={RelativeSource TemplatedParent}}" />
</MenuItem.Header>
<ItemsControl ItemsSource="{Binding PersonCollection}">
<ItemsControl.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" Margin="2" MinWidth="100">
<TextBlock Text="{Binding Value.Text}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</MenuItem>
</Menu>
Note: I need to get the count based on ItemsControl ItemsSource not by the Collection.Count Property. Kindly assist me.
This is the solution:
<Menu>
<MenuItem>
<MenuItem.Header>
<TextBox Text="{Binding ElementName=ItemsControl, Path=Items.Count, Mode=OneWay}" />
</MenuItem.Header>
<ItemsControl x:Name="ItemsControl"
ItemsSource="{Binding Items}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Margin="2"
MinWidth="100">
<TextBlock Text="{Binding Value.Text}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</MenuItem>
</Menu>
Does it work for you?
Related
I created the following control:
public ObservableCollection<User> Users { get; set; } = new();
<CollectionViewSource
x:Key="UsersKey"
IsLiveFilteringRequested="True"
Source="{Binding Users}"/>
<ItemsControl x:Name="ItemsControlUsers" ItemsSource="{Binding Source={StaticResource Users}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" Checked="CheckBox_OnChecked" Unchecked="CheckBox_OnUnchecked" Content="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And this is how it looks:
And I want to add a CheckBox of Select all.
I would like it to look like this:
The most obvious solution would be to just use a StackPanel add a CheckBox before the ItemsControl. In this case the item does not belong to the ItemsControl. Whether this is acceptable or not depends on your requirements.
<StackPanel>
<StackPanel.Resources>
<CollectionViewSource
x:Key="UsersKey"
IsLiveFilteringRequested="True"
Source="{Binding StringItems}"/>
</StackPanel.Resources>
<StackPanel Orientation="Horizontal">
<CheckBox Content="Select all"/>
</StackPanel>
<ItemsControl x:Name="ItemsControlUsers">
<!-- ...other markup. -->
</ItemsControl>
</StackPanel>
Another solution is to use a CompositeCollection that allows you to bind multiple collections and also add single elements. All of the items are then part of the ItemsControl.
<Border>
<Border.Resources>
<CollectionViewSource
x:Key="UsersKey"
IsLiveFilteringRequested="True"
Source="{Binding Users}"/>
</Border.Resources>
<ItemsControl x:Name="ItemsControlUsers">
<ItemsControl.ItemsSource>
<CompositeCollection>
<StackPanel Orientation="Horizontal">
<CheckBox Content="Select all"/>
</StackPanel>
<CollectionContainer Collection="{Binding Source={StaticResource UsersKey}}"/>
</CompositeCollection>
</ItemsControl.ItemsSource>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" Checked="CheckBox_OnChecked" Unchecked="CheckBox_OnUnchecked" Content="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
I am trying to update the Combo ToolTip at the same time as the ComboItems.
<ComboBox x:Name="comboMeetingWeek" ItemsSource="{Binding Meetings}"
SelectedItem="{Binding Meeting, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ToolTip>
<ToolTip DataContext="{Binding Path=PlacementTarget, RelativeSource={RelativeSource Self}}"
Content="{Binding Path=SelectedItem.ToolTipForSpecialEvent}">
</ToolTip>
</ComboBox.ToolTip>
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip="{Binding ToolTipForSpecialEvent}">
<Image Source="Images/Bell.png" Margin="0,0,5,0"
Visibility="{Binding DisplayBellImage, Converter={StaticResource BoolToHiddenConverter}}" Stretch="None"/>
<TextBlock Text="{Binding DateMeetingAsText}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
The ComboBoxItems will always be correct. The but the ComboBox ToolTip won't.
OK, I found the solution. I had to do it like this:
<ComboBox x:Name="comboMeetingWeek" ItemsSource="{Binding Meetings}"
SelectedItem="{Binding Meeting, UpdateSourceTrigger=PropertyChanged}"
ToolTip="{Binding Meeting.ToolTipForSpecialEvent}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" ToolTip="{Binding ToolTipForSpecialEvent}">
<Image Source="Images/Bell.png" Margin="0,0,5,0"
Visibility="{Binding DisplayBellImage, Converter={StaticResource BoolToHiddenConverter}}" Stretch="None"/>
<TextBlock Text="{Binding DateMeetingAsText}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Less code ... even better .. :) But now is always works right.
This link helped.
<DataTemplate x:Key="ItemTemplate">
<DockPanel Width="Auto">
<Button DockPanel.Dock="Top" Tag="{Binding id}">
<Button.Template>
<ControlTemplate >
<Image Source="{Binding image}"/>
</ControlTemplate>
</Button.Template>
</Button>
<TextBlock Text="{Binding title}" HorizontalAlignment="Center" DockPanel.Dock="Bottom"/>
</DockPanel>
</DataTemplate>
<Grid x:Name="LeftGrid" Grid.Row="2" Grid.Column="0" >
<Border BorderThickness="1" BorderBrush="Red">
<ItemsControl ItemTemplate="{StaticResource ItemTemplate}" ItemsSource="{Binding DisplayMovies.View}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</Grid>
I am setting the Tag value of each Button to the value of id. Whenever a Button is selected, I would like to pass this Tag value to a property in my ViewModel.
Could someone please help me out with how I can achieve this? I've always bound from ViewModel to XAML and never the other way around
I should also mention that Binding id is not referring to my ViewModel. It is referring to a property in ItemsSource="{Binding DisplayMovies.View}"
Do you mean something like this?
<Button
Command="{Binding DataContext.YourVmCommand,
RelativeSource={RelativeSource
AncestorType={x:Type ItemsControl}}}}"
CommandParameter="{Binding Id}"
DockPanel.Dock="Top" >
How can every item inside the ItemsControl - here it is a TextBox - show vertical scrollbars ?
I do not want a vertical scrollbar around all Expanders.
Thats the code I tried:
<ItemsControl ScrollViewer.HorizontalScrollBarVisibility="Hidden" ItemsSource="{Binding Path=ErrorLogs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander Margin="0" Header="{Binding FileName}" Background="Green">
<Controls:BindableTextBox Background="Red"
Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You have two options
1, wrap inside a scrollviewer
<DataTemplate>
<Expander Margin="0"
Header="{Binding FileName}"
Background="Green">
<ScrollViewer VerticalScrollBarVisibility="Visible">
<Controls:BindableTextBox Background="Red"
Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</ScrollViewer>
</Expander>
</DataTemplate>
2, enable multiline on textbox
eg.
<DataTemplate>
<Expander Margin="0"
Header="{Binding FileName}"
Background="Green">
<TextBox Background="Red"
AcceptsReturn="True" TextWrapping="Wrap"
Text="{Binding Content, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
</Expander>
</DataTemplate>
I am not sure about Controls:BindableTextBox so using multiline depends on availability
i want those buttons next to each other and not under each other
this is a mvvm, so the buttons are generated by a class
<ItemsControl ItemsSource="{Binding Pages}" Grid.Column="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Margin="8" Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You just have to change the default ItemsPanel from your ItemsControl into a horizontal oriented one, here's an example :
<ItemsControl ...>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Button Margin="8" Content="{Binding Name}" Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" CommandParameter="{Binding}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
By defining an horizontal StackPanel as your ItemsControl panel, each item will be aligned next to each other (Note that the default one is a vertical StackPanel).