I have searched extensively on Google and am struggling to find an easy example to follow for an ItemsControl which I think I need to be able to do the following.
I currently have a Grid with a scrollable Listbox containing Checkboxes which works as expected using the following XAML layout
<Grid>
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Selections}" Margin="12,22,12,94">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}"
Content="{Binding Path=Item.SelectionName}">
</CheckBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I now want to add a TextBox to the right of each Checkbox so it's aligned horizontally with 1 Checkbox and 1 Textbox per row. I thought I would have to use an ItemsControl to allow two controls but using the ItemsControl as below I lose the ability to scroll
<Grid>
<ItemsControl ScrollViewer.VerticalScrollBarVisibility="Auto"
ItemsSource="{Binding Selections}" Margin="12,22,12,94">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsChecked}"
Content="{Binding Path=Item.SelectionName}">
</CheckBox>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Also, if I try and add a textbox similar to
<DataTemplate>
<CheckBox IsChecked="{Binding sChecked}" Content="{Binding Path=Item.BookieName}" />
<TextBox />
</DataTemplate>
I get an error The object 'DataTemplate' already has a child and cannot add 'TextBox'
Essentially, I want it to look like this
Can anyone give me a few pointers on how to structure the controls in XAML to get my desired layout?
Just use a StackPanel in your DataTemplate and set the orientation to horizontal.
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding sChecked}" Content="{Binding Path=Item.BookieName}" />
<TextBox />
</StackPanel>
</DataTemplate>
Related
I've written a code example below:
<StackPanel>
<TextBlock>Appointments today</TextBlock>
<ItemsControl ItemsSource="{Binding Appointments}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<controls:CalendarMonthDayEventsItemsPanel OutsideViewportCount="..." />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border>
<TextBlock Text="{Binding Title}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal">
<TextBlock>+</TextBlock>
<TextBlock Text="{Binding ......}" /> <!-- Should show number of items in ItemsControl that are outside view, using CalendarMonthDayEventsItemsPanel.OutsideViewportCount -->
<TextBlock>more items</TextBlock>
</StackPanel>
</StackPanel>
I Created a custom Panel, the CalendarMonthDayEventsItemsPanel, and I use that panel as the itemspanel of the ItemsControl. In the panel's layout code, I determine how many items (panel childs) are outside the bounds of the panel. The property OutsideViewportCount contains the number of items that are outside of the visible bounds of the CalendarMonthDayEventsItemsPanel.
Now I want to show the value of OutsideViewportCount in a TextBlock that's below the ItemsControl.
This means I have to create some kind of binding, but everything I tried doesn't work.
Does someone have a solution or a better approach to achieve the same result?
Maybe you can make use of Tag property of ItemsPanel to relay the value of ItemsPanel as a workaround.
<ItemsControl x:Name="A"
ItemsSource="{Binding Appointments}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<local:CalendarMonthDayEventsItemsPanel OutsideViewportCount="{Binding RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}, Path=Tag, Mode=OneWayToSource}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
...
</ItemsControl>
<StackPanel Orientation="Horizontal">
<TextBlock>+</TextBlock>
<TextBlock Text="{Binding ElementName=A, Path=Tag, Mode=OneWay}"/>
<TextBlock>more items</TextBlock>
</StackPanel>
I have a ViewModel with about 200 contacts and I am binding it to a ListView
<Grid>
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<ListView x:Name="ContactListing" ItemsSource="{Binding ContactListing}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=DisplayName}" />
<Image Source="{Binding Thumbnail,Converter={StaticResource ResourceKey=contactConv}}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
</Grid>
Would be great if someone could explain the details behind the ScrollViewers visibility
A ListView control already contains a ScrollViewer and implements scrolling based on the amount of items, there is no need to wrap this control in another ScrollViewer. You can double check this in the default ControlTemplate of ListView at line 6219 in the generic.xaml file containing all Windows 10 styles:
C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10240.0\Generic\generic.xaml
So you simply have to remove the ScrollViewer from your XAML fragment.
<Grid>
<ListView x:Name="ContactListing" ItemsSource="{Binding ContactListing}" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=DisplayName}" />
<Image Source="{Binding Thumbnail,Converter={StaticResource ResourceKey=contactConv}}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
Note: As you're using a ListView, I suppose you want all your items stacked above each other. If you want multiple columns to show your items, use a GridView instead.
So I have a few ListViews. The first is binded to ObservaleCollection<ComPort>. All properties of ComPort may take some predefined values. Other ListViews are responsible for that properties: they show all that possible (predefined) values and SelectedItem should be the current value of that property of ComPort from the first ObservaleCollection.
I can't attach images so here is an external picture, it would make the situation clean: http://i.stack.imgur.com/ZBRRx.png
<Window.Resources>
<ResourceDictionary x:Name="rd">
<l:ComPorts x:Key="vComPorts"/>
<l:SystemPorts x:Key="vSystemPorts"/>
<l:BaudRates x:Key="vBaudRate"/>
<l:Parities x:Key="vParities"/>
<l:DataBits x:Key="vDataBits"/>
<l:StopBits x:Key="vStopBits"/>
<l:Timeouts x:Key="vTimeouts"/>
<l:ComPort x:Key="vSelectedPort"/>
</ResourceDictionary>
</Window.Resources>
...
<ListView
Name="PortsList"
Grid.Row="1"
Grid.Column="0"
Margin="5"
VerticalAlignment="Stretch"
ItemsSource="{StaticResource vComPorts}"
DataContext="{StaticResource vComPorts}"
SelectedValuePath="PortName"
SelectedValue="{Binding ElementName=SystemPortsList, Path=SelectedItem.Value}"
SelectionChanged="PortsList_SelectionChanged"
MouseDoubleClick="PortsList_MouseDoubleClick">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox />
<TextBlock Margin="5,0,0,0" Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ListView
x:Name="SystemPortsList"
Margin="5"
VerticalAlignment="Stretch"
DataContext="{Binding Source={StaticResource vSelectedPort}}"
ItemsSource="{Binding Source={StaticResource vSystemPortsView}}"
SelectedItem="{Binding Source={StaticResource vSelectedPort}, Path=PortName}"
MouseEnter="SystemPortsList_Refresh"
MouseLeave="SystemPortsList_Refresh"
Grid.Row="1"
Grid.Column="1" SelectionChanged="SystemPortsList_SelectionChanged">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Name="tb" Margin="5,0,0,0" Text="{Binding Path=Name}" />
</StackPanel>
</ListView.ItemTemplate>
</ListView>
I've tried to make an instance of class ComPort for saving current value of selected item from the first ListView, but anyway I can't cope with it without help. How this task should be solved?
1) Instead of handling SelectionChanged on the PortsList ListView, bind your checkbox to the ListViewItemsPanel like so:
<CheckBox IsChecked={Binding IsSelected, RelativeSource=Parent/>
2) Add an x:Name to your first ListBox, say x:Name="ComPortLB";
3) Remove DataContext on SystemPortsList;
4) Fix SelectedItem on SystemPortsList like so:
SelectedValue="{Binding ElementName=ComPortLB, Path=SelectedValue.PortName}"
I haven't tested any of this code and I haven't done this kind of stuff for a while, so I apologize for errors, but it should get you closer. I've also had to make some assumptions about your classes since you don't provide enough information.
My problem is my checkbox content doesnt display underscores or the & symbol. I've read about the RecognizeAccessKey attribute, but i can't get it working. My listbox looks like this:
<ListBox ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Channels}">
<ListBox.ItemTemplate>
<DataTemplate>
<ContentPresenter RecognizesAccessKey="False">
<CheckBox Content="{Binding Item}"
IsChecked="{Binding IsChecked}"
Width="149"
MinWidth="149" />
</ContentPresenter>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Can anybody tell me how to get this fixed, so my Checkbox's content will display underscores and & symbols?
thank you very much!
You could use TextBlock as CheckBox.Content, instead of binding it directly, and bind its Text property
<CheckBox IsChecked="{Binding IsChecked}" Width="149" MinWidth="149">
<CheckBox.Content>
<TextBlock Text="{Binding Item}"/>
</CheckBox.Content>
</CheckBox>
By default CheckBox will wrap TextBlock in AccessText when it displays Content
I'm trying to bind my stackpanel's visibility to the checkbox's isChecked value. It's a common problem, but I just can't figure it out.
Converter:
<Page.Resources>
<common:BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Page.Resources>
StackPanel I want to mess with(I removed some code, so don't you worry about listview's binding, I set it in c#):
<ListView x:Name="aktualniGracze" ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackLiczymy" Visibility="{Binding isChecked, ElementName=czyLiczymy, Converter={StaticResource BoolToVis}}">
<TextBlock Text="{Binding ileWypil}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
CheckBox:
<CheckBox Name="czyLiczymy"/>
Nothing happens when I change the state of the checkbox, any clues?
Thanks a lot in advance.
If you have your correct DataContext in CheckBox, I think you are just missing the DataContext.isChecked
<ListView x:Name="aktualniGracze" ItemsSource="{Binding}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="stackLiczymy" Visibility="{Binding DataContext.isChecked, ElementName=czyLiczymy, Converter={StaticResource BoolToVis}}">
<TextBlock Text="{Binding ileWypil}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>