Bind Tag to ViewModel Property - c#

<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" >

Related

Adding button outside the binded Listbox in xaml

I have encountered a problem - i have created a project where i bind my code to xaml by using a bind to the listbox. However, it has created some problems in my future code - i want to add button to my form, but i encounter some errors.
'Items collection must be empty before using ItemsSource.'
This Error occurs when i try to bind something outside of my bindable Listbox.
The property "VisualTree" can only be set once.
This Error occurs when i try to add button underneath the Listbox.
Can someone guide me on how can i fix this?
My code:
<ListBox x:Name="ItemsControl1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5">
</UniformGrid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2" Width="Auto" Height="Auto">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number}"/>
<Image Source="{Binding Source}" Margin="0,0,5,0"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
The desirable result would be a button under the listbox.
You should add your button below ListBox declaration.
Exceptions you are facing are thrown because visual tree is populated via binding and you cannot alter it manually anymore.
You will need to put all this stuff inside of some layout container (Grid, StackPanel, etc.), since you cannot set Window's/UserControl's Content property twice:
<StackPanel>
<ListBox x:Name="ItemsControl1">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="5">
</UniformGrid>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="2" Width="Auto" Height="Auto">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number}"/>
<Image Source="{Binding Source}" Margin="0,0,5,0"/>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button/>
</StackPanel>

Bind Count of ItemsSource of an ItemsControl in a TextBlock using WPF

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?

How can i make sure each items's margin inside a wrap panel is the same?

I have an ItemsControl which has a WrapPanel as its ItemsPanelTemplate. I am trying to organise a collection of buttons so that each button has the same margin on its left and right side. Here is the code I have so far:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<ItemsControl HorizontalAlignment="Stretch" ItemsSource="{Binding SystemData.PlayersList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Gray" Margin="5">
<Button Width="180"
Style="{Styles:MyStyleRef ResourceKey=BrowserItemStyle}">
<DockPanel LastChildFill="True">
<Image Source="{Binding Icon}" Style="{Styles:MyStyleRef ResourceKey=DriveImageStyle}"/>
<Label HorizontalAlignment="Left" Content="{Binding Name}" Style="{Styles:MyStyleRef ResourceKey=DriveLabelStyle}"/>
</DockPanel>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
And here is how it looks:
When i set the WrapPanel's HorizontalAlignment to 'Center' I get closer to the result i want.
I would like each Item to have the same margin either side of it so that it creates a uniform grid of controls - Is this possible?
Regards, Tim.
Ok got it solved... I completely over looked the uniform grid control.
Here is my code now:
<ScrollViewer HorizontalAlignment="Stretch" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<ItemsControl HorizontalAlignment="Stretch" VerticalAlignment="Top" ItemsSource="{Binding SystemData.PlayersList}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="6"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="Gray" Margin="5" Height="40">
<Button
Style="{Styles:MyStyleRef ResourceKey=BrowserItemStyle}">
<DockPanel LastChildFill="True">
<Image Source="{Binding Icon}" Style="{Styles:MyStyleRef ResourceKey=DriveImageStyle}"/>
<Label HorizontalAlignment="Left" Content="{Binding Name}" Style="{Styles:MyStyleRef ResourceKey=DriveLabelStyle}"/>
</DockPanel>
</Button>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

Show scrollbars on ItemsControl item

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

Styling Dynamically created TextBoxes

I am using the MVVM pattern which is really new to me. I click 'Add Title' and at the moment the textbox shows, and same happens when I click 'Add Question'. The thing that is wrong is that they show up exactly below each other. When they click 'Add Title' I want the text boxes to show with a margin from the left of '20' and then when I click 'Add Question' I want the margin to show as '40'. They also need to have a space of '20' between all text boxes so there not directly underneath the textbox.
XAML CODE:
<Grid>
<Button Content="Add Question" Command="{Binding AddQuestionCommand}" Margin="615,19,179,724" />
<Button Content="Add Title" Command="{Binding AddTitleCommand}" Margin="474,19,320,724" />
<StackPanel>
<ItemsControl ItemsSource="{Binding Title}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Question}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
I have tried to add the Padding property but it makes the text boxes bigger in height, and also I have tried the Margin but all text boxes are created dynamically.
Try this
adjust margin according to your requirement
<Grid>
<Button Content="Add Question" Command="{Binding AddQuestionCommand}" Margin="615,19,179,724" />
<Button Content="Add Title" Command="{Binding AddTitleCommand}" Margin="474,19,320,724" />
<StackPanel>
<ItemsControl ItemsSource="{Binding Title}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="20,20,0,0"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl ItemsSource="{Binding Question}">
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="FrameworkElement.Margin" Value="40,20,0,0"/>
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
A good way to define appearance structure is using the Grid control, specifying a row and a column.
Try something like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ItemsControl Grid.Column="0" ItemsSource="{Binding Title}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<ItemsControl Grid.Column="1" ItemsSource="{Binding Question}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding .}" Width="200" HorizontalAlignment="Left"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Categories