I have collection of Images and I need create something like carousel with bullets.
Currently I have 2 ListBoxes
<ListBox Name="lb" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0" ScrollViewer.HorizontalScrollBarVisibility="Auto"
IsSynchronizedWithCurrentItem="True"
ItemsPanel="{StaticResource HorizontalItemsPanel}"
ItemsSource="{Binding Source={StaticResource CharacterCollectionView}}"
ItemContainerStyle="{StaticResource CharacterContainerStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<Image Source="{Binding SelectedItem.Image, ElementName=lb1}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox BorderThickness="0" Height="20" VerticalAlignment="Top" IsSynchronizedWithCurrentItem="True" Background="#66000000" Grid.Row="1" Name="lb1" ItemsSource="{Binding Source={StaticResource CharacterCollectionView}}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="0" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#FFFFFF"/>
</Trigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="#4CFFFFFF" Width="6" Height="6" CornerRadius="3"></Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
1st ListBox for Images, 2nd - for bullets to change image. If click on Bullets, images changes correctly (Under change I mean setting image as selected, cause only selected items is visible)
But I need to add functionality to slide Images also without using that bullets (when you can slide images by touch or by sliding horizontaly). Currectly this only work when all images is visible.
How to make sliding for images when only selected item is visible?
Related
I have an ItemsControl that contains a textbox for each binding item and I want to allow overlaying text box content if its content is wider than the textbox width similar to excel cells overlaying behavior.
Is there a way to do this?
<ItemsControl ItemsSource="{Binding Path=MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Width="100"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}" TextWrapping="WrapWithOverflow"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
You can use tooltip for that. You just need to bind the source with itself.
<ListView ItemsSource="{Binding Path=MyStringCollection}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Width="100"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding}" TextWrapping="WrapWithOverflow" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=Text}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
For further information:
DrawToolTip Event
Set ToolTipSize
To replicate a similar behavior, you can make use of a Popup.
To implement a similar behavior, you first must disable content wrapping of your TextBox.
Then replace the current TextBox with a TextBlock, which is used to display the text.
The Popup, which actually contains the editable TextBox, will then overlay this TextBlock at the exact position, thus hiding the TextBlock to make it appear to stretch and overlay the adjacent items.
A MultiTrigger will close the Popup as soon as the focus moved outside the ListBoxItem.
To improve performance you should use the VirtualizingStackPanel as items host.
<ListView ItemsSource="{Binding MyStringCollection}"
HorizontalAlignment="Left"
Width="800">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Border BorderThickness="1"
BorderBrush="Gray">
<TextBlock Text="{Binding}" />
</Border>
<Popup x:Name="EditableTextSiteHost"
PlacementTarget="{Binding ElementName=TextSite}"
Placement="Relative"
Height="{Binding ElementName=TextSite, Path=ActualHeight}"
AllowsTransparency="True"
FocusManager.FocusedElement="{Binding ElementName=EditableTextSite}">
<TextBox x:Name="EditableTextSite"
Text="{Binding TextData}" />
</Popup>
</Grid>
<DataTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsSelected}"
Value="True" />
<Condition Binding="{Binding RelativeSource={RelativeSource AncestorType=ListBoxItem}, Path=IsKeyboardFocusWithin}"
Value="True" />
</MultiDataTrigger.Conditions>
<Setter TargetName="EditableTextSiteHost"
Property="IsOpen"
Value="True" />
</MultiDataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<!-- Make items overlap -->
<Setter Property="Margin"
Value="-2,0,0,0" />
<Setter Property="Padding"
Value="0" />
<Setter Property="Width"
Value="50" />
<Style.Triggers>
<!-- Apply zero Margin on the first item -->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}"
Value="{x:Null}">
<Setter Property="Margin"
Value="0,0,0,0" />
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
To-do
This is just a raw example, a proof of concept. You would have to improve the behavior. For example, you would want to close the Popup when the user scrolls or moves the Window. Otherwise, since Popup itself is a Window, the Popup would not move to follow the placement target. You could move the related logic to an attached behavior.
You likely also want to improve the selection behavior. Currently the selection highlight border does not (virtually) extend to surround the Popup. You have to mimic this by applying a Border on the TextBox that will replicate the ListBoxItem highlight border.
I managed to produce the excel cells overlay behavior by using a Grid with dynamic column count using this helper dependency properties https://rachel53461.wordpress.com/2011/09/17/wpf-grids-rowcolumn-count-properties/ as a container template of ItemsControl and binding the column index of each textbox to the ordered item index and binding Grid.ZIndex to the reversed index to be displayed above the adjacent text boxes.
<ItemsControl ItemsSource="{Binding MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid HorizontalAlignment="Left" helpers:GridHelpers.ColumnCount="{Binding MyCollection.Count}"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column" Value="{Binding ItemIndex}"/>
<Setter Property="Grid.ZIndex" Value="{Binding ReversedIndex}" />
<Setter Property="Grid.ColumnSpan" Value="{Binding MaxMergedCells}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
<TextBox MinWidth="30" Text="{Binding }"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
I have a ListView that contains Image as the Items. I want the width of each image to follow the width of the ListView whenever I resize the Grid that contains it.
<!--Playlists-->
<Grid Column="0">
<ListView Grid.Row="1" Grid.Column="1"
HorizontalAlignment="Stretch"
... >
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<!--Images-->
<ListView.ItemTemplate>
<DataTemplate DataType="{x:Type models:PlaylistModel}">
<Grid HorizontalAlignment="Stretch">
<Image Source="{Binding ImagePath}"
Stretch="Uniform">
</Image>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
<GridSplitter Grid.Column="0" />
Source: http://www.teixeira-soft.com/bluescreen/2016/03/21/c-how-to-make-a-panel-within-a-datatemplate-fill-the-entire-width-of-a-listview-or-itenscontrol-derivative/
This is what happens
As seen here, the width of the image doesn't resize at all. The image size just stays the same even when the size of the ListView changes. However, if I set the width of the Grid inside of DataTemplate then the Image would actually follow that width.
Looks like it was a mistake to use ListView. Changing everything to a ListBox fixed it for me.
Leaving this here if someone encounters the same problem.
<ListBox HorizontalAlignment="Stretch">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type models:PlaylistModel}">
<Image Source="{Binding ImagePath}"
Stretch="Uniform" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I'm having trouble enabling drag (as in drag&drop) in an UWP ListBox. The selection stops working when I do that.
I have an UWP ListBox that contains an ItemTemplate with a single TextBlock in it. Everything was fine with the selection of items until I enabled CanDrag (i.e. drag&drop) on the TextBlock in the ListItem. After this I can't select items in the ListBox any longer by clicking on the items in the list. I can change selection by moving the focus with the arrow keys but selection with mouse interaction is no longer possible. If I set CanDrag back to False, selection starts working again.
Am I doing something wrong?
<ScrollViewer Grid.Column="0" HorizontalScrollMode="Disabled" VerticalScrollMode="Auto">
<ListBox x:Name="addProcessorListBox" ItemsSource="{Binding ProcessorTypes}"
SelectionMode="Single" DoubleTapped="OnDoubleTapped">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Margin="8,2,10,2" Text="{Binding Key}" FontSize="15" FontWeight="Bold"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListBox.GroupStyle>
<ListBox.ItemTemplate>
<DataTemplate x:DataType="models:ProcessorType">
<TextBlock Grid.Column="0" Margin="18,8,10,8" Text="{Binding DisplayName}" FontSize="15" CanDrag="True" DragStarting="Processor_DragStarting"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
I tried changing the ListBox to a ListView, but the same behavior persists, i.e. selection does not work when clicking on the text.
I can reproduce this issue. I've reported it to the relevant team. They're investigating this issue.
As a workaround, you could use ListView control, but you do not need to drag the TextBlock in its ItemTemplate. You could choose to drag the whole ListViewItem by setting CanDragItems="True" and handling the DragItemsStarting event.
<ListView x:Name="addProcessorListBox" ItemsSource="{Binding ProcessorTypes}"
SelectionMode="Single" DoubleTapped="AddProcessorListBox_DoubleTapped" CanDragItems="True" DragItemsStarting="AddProcessorListBox_DragItemsStarting">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Padding" Value="0" />
</Style>
</ListView.ItemContainerStyle>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Margin="8,2,10,2" Text="{Binding Key}" FontSize="15" FontWeight="Bold" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Grid.Column="0" Margin="18,8,10,8" Text="{Binding DisplayName}" FontSize="15" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
We have confirmed that the best approach is ListView as we have it implemented in our github sample here
Actually the problem isn't quite related to ListBox/ListView but with
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
The following doc mentions that Stretch will stretches the child element to fill the allocated space of the parent element. But in this case, what is the size of parent space? Selection won't fail if specified Left/Right/Center but only with Stretch.
So actually this is a coding issue and you will need the property to set the size of parament element.
I would like to ask you, if is possible to have ItemsControl without background (x:null), not transparent.
I have collection with data, and these are showed in ItemsControl with help of DataTemplate. Some data in datatemplate are collapsed, and I need to be able to clickable on another control behind the itemscontrol.
Here is example what I mean:
<Button x:Name="bt_behind"></Button>
<ItemsControl ItemsSource="{Binding ListOfData}" Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="{x:Null}"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type Class:Data}">
<Grid Width="100" Background="{x:Null}">
<Rectangle x:Name="rec" Fill="Red" Height="100" Visibility="Collapsed">
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="true">
<Setter TargeName="rec" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Example where item3 is partly collapsed and marked area, where is empty place
I set everywhere the background to null (try itemcontainerstyle too), but without success. On button behind ItemsControl still is not clickable. I think that ItemsControl have transparent background for events, but is it possible to remove this background?
Thanks for any advice and sorry for my english:)
-pav-
Well, as i said, it's all working. Fixed XAML:
<Grid>
<Button x:Name="bt_behind" Content="behind" Click="Bt_behind_OnClick"/>
<ItemsControl ItemsSource="{Binding ListOfData}" Background="{x:Null}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Background="{x:Null}"></StackPanel>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Data}">
<Grid Width="100" Background="{x:Null}">
<Rectangle x:Name="rec" Fill="Red" Height="100" Visibility="Collapsed"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="true">
<Setter TargetName="rec" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
Just for test.
private void Bt_behind_OnClick(object sender, RoutedEventArgs e)
{
MessageBox.Show("");
}
I have ToggleButtons that are dynamically created based on my datasource. I would like to have only one togglebutton checked at a time when a user clicks one. How can I accomplish this?
<UserControl.Resources>
<ItemsPanelTemplate x:Key="HorizontalMiniDrawerList">
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
<DataTemplate x:Key="MiniDrawerRowTemplate">
<ToggleButton x:Name="_MiniDrawerButton" Width="60" Height="85" Style="{DynamicResource MiniDrawerButtonWhite}" Checked="_MiniDrawerButton_Checked" >
</ToggleButton>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Width}" Value="3">
<Setter TargetName="_MiniDrawerButton" Property="Width" Value="185"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="MiniDrawerListItemTemplate">
<ListBox SelectionMode="Multiple" Background="#00000000" BorderThickness="0" Width="500"
ItemsPanel="{StaticResource HorizontalMiniDrawerList}"
ItemTemplate="{StaticResource MiniDrawerRowTemplate}"
ItemsSource="{Binding Row}" >
</ListBox>
</DataTemplate>
</UserControl.Resources>
<Grid Background="{DynamicResource ListBackgroundColor}" >
<ListBox x:Name="_MiniDrawerRows" BorderThickness="0" Background="Transparent" Margin="107,84,225,217" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ItemsSource="{Binding Path=MiniDrawerRows, diagnostics:PresentationTraceSources.TraceLevel=High}"
ItemTemplate="{StaticResource MiniDrawerListItemTemplate}" >
</ListBox>
</Grid>
Update: Instead of using a togglebutton I used a radiobutton and changed the style of the radio button to look like a togglebutton.
<Style x:Key="MiniDrawerButtonWhiteRadioToToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}" TargetType="{x:Type RadioButton}">
I assume you mean "only one" instead of "only when". In that case you can use RadioButton (which is derived from ToggleButton) instead and set a GroupName on _MiniDrawerButton in your ItemTemplate. It looks like you are probably already using a custom ControlTemplate so you can use the same one for RadioButton by just changing the Style and ControlTemplate TargetTypes.