Adding Scrollbar to ItemsControl - wpf

I have a long list coming from my Business logic which I need to display on the UI. As the list is long, I tried adding Scrollviewer but I am unable to scroll.
please find the XAML code below
<Grid Margin="0,32,0,0">
<TextBlock Text="{Binding IDC_WiFi, Source={StaticResource Resources}}" FontFamily="Segoe UI" FontSize="20" Foreground="#4cb5ab" HorizontalAlignment="Left" />
<Button Command="{Binding HardwareWifiAccordionCommand}" BorderThickness="0" Width="16" HorizontalAlignment="Right" Height="16" >
<Button.Background>
<ImageBrush ImageSource="{Binding AccordionImageHardwareWifi}" />
</Button.Background>
</Button>
</Grid>
<TextBlock Text="Klein's, Anil's" FontFamily="Segoe UI" FontSize="15" Foreground="#8fa3ad"/>
<StackPanel Height="200" Visibility="{Binding IsAccordionHardwareWifi, Converter={StaticResource Bool2Visible}}">
<ScrollViewer VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding WifiList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,32,0,0">
<Grid>
<Image Source="/Images/Assets/da_wifi1_16x16.png" Height="16" Width="16" HorizontalAlignment="Left" />
<TextBlock Margin="25,0,0,0" Text="{Binding NetworkName}" FontSize="15" Foreground="#FFFFFF" />
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Right" />
</Grid>
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>

Put it into a ScrollViewer.
<ScrollViewer>
<StackPanel >
</StackPanel>
</ScrollViewer>

As #StepUp points out you can just wrap it with a ScrollViewer but I believe this breaks virtualization. That's outside the scope of this question of course but it's something to keep in mind. If performance is likely to become an issue then I'd suggest implementing this as shown in the answer to this question.

The scrollviewer needed a Height to be set
<Grid Margin="0,32,0,0">
<TextBlock Text="{Binding IDC_WiFi, Source={StaticResource Resources}}" FontFamily="Segoe UI" FontSize="20" Foreground="#4cb5ab" HorizontalAlignment="Left" />
<Button Command="{Binding HardwareWifiAccordionCommand}" BorderThickness="0" Width="16" HorizontalAlignment="Right" Height="16" >
<Button.Background>
<ImageBrush ImageSource="{Binding AccordionImageHardwareWifi}" />
</Button.Background>
</Button>
</Grid>
<TextBlock Text="Klein's, Anil's" FontFamily="Segoe UI" FontSize="15" Foreground="#8fa3ad"/>
<StackPanel Height="200" Visibility="{Binding IsAccordionHardwareWifi, Converter={StaticResource Bool2Visible}}">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="350">
<ItemsControl ItemsSource="{Binding WifiList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,32,0,0">
<Grid>
<Image Source="/Images/Assets/da_wifi1_16x16.png" Height="16" Width="16" HorizontalAlignment="Left" />
<TextBlock Margin="25,0,0,0" Text="{Binding NetworkName}" FontSize="15" Foreground="#FFFFFF" />
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Right" />
</Grid>
<TextBlock Text="" FontSize="15" Foreground="#8fa3ad" HorizontalAlignment="Left" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</StackPanel>

Related

How to bind a Command to ItemsControl's template

I have to create an ItemsControl like below and a view model with a clickcommand. How can I bind the command to its template?
<ItemsControl Name="connStatusList" HorizontalAlignment="Left" VerticalAlignment="Top" Background="#e0e0e0" Margin="0,0,0,0" MinHeight="325" Width="1700" ItemsSource="{Binding }" >
<ItemsControl.Template>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<Border>
<ItemsPresenter/>
</Border>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Name="wp" HorizontalAlignment="Left" VerticalAlignment="Top" Orientation="Horizontal" Background="#ededed" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel Width="135" Height="160" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,1,0,0" >
<WrapPanel Background="{StaticResource connRectangle}" Width="133" Height="128">
<Image Source="{Binding WifiImage}" Width="70" Height="53" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,2,0,0"/>
<Image Source="{Binding ConnectedImage}" Width="43" Height="63" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="45,7,0,0" />
</WrapPanel>
<WrapPanel>
<Label Content="{Binding ItemNO}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="35,0,0,0" FontWeight="Bold" FontSize="18"></Label>
<Label Content="{Binding Connected}" Name="lblconnected" Visibility="Collapsed"></Label>
</WrapPanel>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
As you are essentially creating a list of buttons, use a Button in your template to bind the command. I assume your command property is called ClickCommand. You might need to adapt the style of the button e.g. in mouse-over state to fit your application.
<DataTemplate>
<Button Command="{Binding ClickCommand}">
<Button.Content>
<WrapPanel Width="135" Height="160" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,1,0,0" >
<WrapPanel Background="{StaticResource connRectangle}" Width="133" Height="128">
<Image Source="{Binding WifiImage}" Width="70" Height="53" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,2,0,0"/>
<Image Source="{Binding ConnectedImage}" Width="43" Height="63" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="45,7,0,0" />
</WrapPanel>
<WrapPanel>
<Label Content="{Binding ItemNO}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="35,0,0,0" FontWeight="Bold" FontSize="18"></Label>
<Label Content="{Binding Connected}" Name="lblconnected" Visibility="Collapsed"></Label>
</WrapPanel>
</WrapPanel>
</Button.Content>
</Button>
</DataTemplate>
Alternatively, you could use an event trigger from the Microsoft.Xaml.Behaviors.Wpf NuGet package. With this approach, the ClickCommand is invoked on mouse button up, it does not change any style.
<DataTemplate>
<WrapPanel Width="135" Height="160" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,1,0,0">
<b:Interaction.Triggers>
<b:EventTrigger EventName="MouseLeftButtonUp">
<b:InvokeCommandAction Command="{Binding ClickCommand}"/>
</b:EventTrigger>
</b:Interaction.Triggers>
<WrapPanel Background="{StaticResource connRectangle}" Width="133" Height="128">
<Image Source="{Binding WifiImage}" Width="70" Height="53" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="35,2,0,0"/>
<Image Source="{Binding ConnectedImage}" Width="43" Height="63" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="45,7,0,0" />
</WrapPanel>
<WrapPanel>
<Label Content="{Binding ItemNO}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="35,0,0,0" FontWeight="Bold" FontSize="18"></Label>
<Label Content="{Binding Connected}" Name="lblconnected" Visibility="Collapsed"></Label>
</WrapPanel>
</WrapPanel>
</DataTemplate>

Get binding from listbox item label

I have a listbox in WPF which consists of few labels and a rectangle.
I am trying to get all the label values of items in a ListBox.
My WPF markup for ListBox is:
<ListBox x:Name="izabraniList" ItemTemplate="{DynamicResource izabraniIzbornik}" Margin="0,80,10,108" HorizontalAlignment="Right" Width="289" Background="{x:Null}" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<ListBox.Resources>
<DataTemplate x:Key="izabraniIzbornik">
<Border BorderBrush="white" CornerRadius="2,2,2,2" BorderThickness="1,1,1,1">
<StackPanel Orientation="Horizontal" Width="254" Height="64" UseLayoutRounding="False" Opacity="100">
<DockPanel>
<Rectangle Height="62" Width="62"
Margin="2,0" RadiusX="5" RadiusY="5" >
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding Path=ART_SIFRA, Converter={StaticResource ImageSourceConverter}}"/>
</Rectangle.Fill>
</Rectangle>
</DockPanel>
<DockPanel Width="133" >
<Label Content="{Binding ART_NAZIV}"
VerticalAlignment="Center"
HorizontalAlignment="left"
FontSize="12" Width="auto" Foreground="#FF303030" FontWeight="Bold" />
</DockPanel>
<DockPanel HorizontalAlignment="right" Width="55" Height="64">
<DockPanel HorizontalAlignment="Right" VerticalAlignment="top" Height="20" FlowDirection="RightToLeft"/>
<DockPanel HorizontalAlignment="Right" VerticalAlignment="bottom" Height="64" FlowDirection="RightToLeft" Width="55">
<Label x:Name="cijena" Content="{Binding SKC_PRICE}" FontSize="11" DockPanel.Dock="Right" HorizontalAlignment="Center" VerticalAlignment="Center" FontWeight="Bold" Width="55" />
<Label Content="{Binding kolicina}" FontSize="11" DockPanel.Dock="Right" HorizontalAlignment="left" VerticalAlignment="top" FontWeight="Bold" Width="55" />
</DockPanel>
</DockPanel>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.Resources>
</ListBox>
And I would like to do something like this:
For Each i As String In izabraniList.Items("SKC_PRICE")
Console.WriteLine(i)
Next
make a separate property in your class that flattens the list (i.e.
public string property { get { return String.Join(", ", izabranilist.Select(x => x.Skc_Price).toarray()); } }
and then bind that to the label.

Pop up is not opening after Rebinding the DataGrid

I have started to work on WPF recently. Currently I am facing an issue.
I have a window , inside that i have an user control which Contains DataGrid, Combobox ,Buttons and a Pop Up.
I am binding DataGrid with List of Notes(string) with Delete Buttons.So when we click on that Button, the pop up will open and Pop up has confirmation message with Yes or No button.
When i click the Yes button i am deleting the Note and Rebinding only the DataGrid.And after that when i click on the Delete Button the pop up is not opening.
If I dont Rebind the DataGrid, in that case PopUp is opening but the problem is deleted Note is still there in the DataGrid though that is deleted from the database, which make confusion whether the Note is deleted or not. That is why I am rebinding.
But Rebinding cause the issue of not opening Popup.
Please help me out how can i get this done.
My Pop up looks like this:
<Popup x:Name="Popupdelete"
AllowsTransparency="True"
HorizontalOffset="-10"
VerticalOffset="10"
Placement="Mouse"
StaysOpen="False"
IsOpen="{Binding IsDeletePopUpOpen}">
<Grid x:Name="LayoutRoot" Background="Transparent" Height="105">
<!-- My confirmation message and Yes No button goes Here-->
</Grid>
IsDeletePopUpOpen is set in the ViewModel.
Thanks & Regards,
Joy
Code goes here:
<-- Delete Pop Up-->
<Popup x:Name="Popupdelete"
AllowsTransparency="True"
HorizontalOffset="-10"
VerticalOffset="10"
Placement="Mouse"
StaysOpen="False"
IsOpen="{Binding IsDeletePopUpOpen}">
<Grid x:Name="LayoutRoot" Background="Transparent" Height="105">
<Border BorderBrush="#E2E2E2" BorderThickness="6" Background="White">
<Grid>
<TextBlock TextWrapping="Wrap" Margin="10,10,10,50" Foreground="#454545" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="Auto" Text="Are you sure you want" />
<TextBlock TextWrapping="Wrap" Margin="50,15,50,25" Foreground="#454545" FontWeight="SemiBold" HorizontalAlignment="Center" VerticalAlignment="Center" Height="30" Width="Auto" Text="to delete?"/>
<Button Content="Yes" Margin="35,50,80,0" Height="40" HorizontalAlignment="Center" VerticalAlignment="Center" Command="{Binding DeleteYesCmd}" CommandParameter="{Binding SelectedItem, ElementName=lstCustomer}" Style="{StaticResource SaveButtonStyle}" />
<TextBlock Text="or" Margin="75,50,60,15" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="#919191" FontSize="10" />
<TextBlock Margin="95,48,35,12" HorizontalAlignment="Center" VerticalAlignment="Center" ><Hyperlink Command="{Binding DeleteNoCmd}"><Run Text="No" FontWeight="Bold" FontSize="12"/></Hyperlink></TextBlock>
</Grid>
</Border>
</Grid>
</Popup>
<--List Of Notes with Delete Image Button-->
<Border Background="#F0F0F0" CornerRadius="0" Visibility="{Binding NotesListViewVisibility}">
<ScrollViewer x:Name="scrollMe" CanContentScroll="True" Height="80" >
<Border Background="White" CornerRadius="5,0,0,5">
<Grid Background="White" Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="101*"/>
<ColumnDefinition Width="35*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="lstCustomer" BorderBrush="Transparent" BorderThickness="0" ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" RequestBringIntoView="RemoveScrollViewFocus"
ItemsSource="{Binding OutcomeNotesView , Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ScrollViewer.VerticalScrollBarVisibility="Disabled" SelectionMode="Single"
Background="#FFFFFF" ItemContainerStyle="{StaticResource ListviewItemContainerStyle}" Grid.ColumnSpan="2">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UC:NoteStackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Border BorderBrush="#E6E6E6" BorderThickness="0,0,0,1"
Width="{Binding ActualWidth, Converter={StaticResource widthconv}, ElementName=lstCustomer}">
<StackPanel x:Name="spNotes" Orientation="Vertical" Margin="0,10,0,10" >
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left" Orientation="Horizontal">
<Button x:Name="btnPrimaryOfficer" MouseEnter="SetEmployeePopUpPlacement" Style="{StaticResource AuthButton}"
CommandParameter="{Binding}" Command="{Binding DataContext.OutcomeEmployeePopUp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}">
<Button.Visibility>
<MultiBinding Converter="{StaticResource ActiveInactiveConv}" ConverterParameter="Hyper">
<Binding Path="EmployeeInfo.ActiveStatusCode"/>
<Binding Path="EmployeeInfo.Id"/>
</MultiBinding>
</Button.Visibility>
<Button.InputBindings>
<MouseBinding Gesture="LeftDoubleClick" CommandParameter="{Binding}"
Command="{Binding DataContext.OutcomeEmployeePopUp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"/>
</Button.InputBindings>
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource imgUser}" Width="15" Height="15" HorizontalAlignment="Left" />
<TextBlock Text="{Binding EmployeeInfo.Name}" Style="{StaticResource AuthEditProfile}" FontFamily="{StaticResource FontBold}" FontSize="12" Margin="2,0,0,0" />
</StackPanel>
</Button>
<StackPanel Orientation="Horizontal" >
<StackPanel.Visibility>
<MultiBinding Converter="{StaticResource ActiveInactiveConv}" ConverterParameter="Normal">
<Binding Path="EmployeeInfo.ActiveStatusCode"/>
<Binding Path="EmployeeInfo.Id"/>
</MultiBinding>
</StackPanel.Visibility>
<!--Visibility="{Binding PrimaryOfficerActiveStatusCode,Converter={StaticResource ActiveInactiveConv},ConverterParameter=Normal}">-->
<Image Source="{StaticResource imgUserBlack}" Width="15" Height="15" HorizontalAlignment="Left" />
<TextBox Text="{Binding EmployeeInfo.Name}" Style="{StaticResource TextWithoutHyperlink}" Margin="2,0,0,0" />
</StackPanel>
<TextBlock Background="Transparent" Text="on"
FontFamily="{StaticResource FontMedium}" FontSize="12" Foreground="#919191" Margin="4,0,2,0"
VerticalAlignment="Bottom" HorizontalAlignment="Center"/>
<TextBox Text="{Binding AddedDate, StringFormat=\{0:MM/dd/yy\}}" Foreground="#454545" VerticalAlignment="Bottom" MaxLength="{Binding Length}"
HorizontalAlignment="Center" Margin="2,0,0,0" Style="{StaticResource ContentText}"/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right" Visibility="{Binding DataContext.DeleteNoteVisibility, ElementName=OutcomeNotesView}" Orientation="Horizontal">
<StackPanel Orientation="Horizontal" >
<Button x:Name="btnDelete" Width="Auto" MouseEnter="btnDelete_MouseEnter" MouseLeave="btnDelete_MouseLeave"
CommandParameter="{Binding}"
Command="{Binding DataContext.LoadDeletePopUp, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}}"
Style="{StaticResource AuthButton}">
<StackPanel Orientation="Horizontal">
<Image Source="{StaticResource imgdeleteicon}" Style="{StaticResource AuthImage}"/>
</StackPanel>
</Button>
</StackPanel>
</StackPanel>
</Grid>
<StackPanel >
<TextBox Text="{Binding Note}" Foreground="#454545" TextWrapping="Wrap" Height="Auto"
Width="{Binding ActualWidth, Converter={StaticResource widthconv}, ElementName=lstCustomer}"
Style="{StaticResource ContentText}" FontFamily="{StaticResource FontNormal}" FontSize="12" Padding="0"/>
<TextBlock x:Name="txtSavingNoteId" Visibility="Collapsed" Text="{Binding NoteId}" />
</StackPanel>
</StackPanel>
</Border>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Border>
</ScrollViewer>
</Border>
</StackPanel>
public List<ActivityNotesDto> OutcomeNotesView
{
get
{
return outcomeNotesView;
}
set
{
outcomeNotesView = value;
OnPropertyChanged("OutcomeNotesView");
}
}
DeleteActivityNote(deletingNoteDetails);
OutcomeNotesView = GetActivityNotesList();
Please let me know if i am missing something.Since first time when i click button Delete popup is opening and it is deleting but next time when i click on the Delete image it didnt open the pop up.
Thanks & Regards,
Joy

Put TextBlock on top of another TextBlock

I tried to implement case in which one TextBlock appears on top of another TextBlock, playing with Visibility property - but it doesn't working yet.
TextBlock are inside DockPanel:
<DockPanel Grid.Row="1" Margin="5">
<TextBlock Text="Text1" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right">
<TextBlock Text="Text2" Background="Aqua" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding IfDeviceSelected, NotifyOnSourceUpdated=True, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}" />
</TextBlock>
<TextBlock Text="#Device Focus:" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right" />
</DockPanel>
You will want to use a Grid to group these TextBlocks, DockPanel/StackPanel will not allow overlapping controls(without horrible manipulation of Margins etc)
<DockPanel Grid.Row="1" Margin="5" >
<Grid DockPanel.Dock="Right" >
<TextBlock Text="Text1" />
<TextBlock Text="Text2" Background="Aqua" Visibility="{Binding IfDeviceSelected, NotifyOnSourceUpdated=True, Converter={StaticResource ResourceKey=BoolToVisibilityConverter}}" />
</Grid>
<TextBlock Text="#Device Focus:" Height="20" HorizontalAlignment="Right" DockPanel.Dock="Right" />
</DockPanel>

Passing Click Events in Composite WPF/XAML Controls

So, let's say I have a DataTemplate:
<DataTemplate x:Key="ProjectsDataItemTemplate">
<ComboBoxItem x:Name="ProjectComboBox"
Opacity="1" HorizontalAlignment="Stretch"
Foreground="#FF80BBD2"
VerticalAlignment="Center" VerticalContentAlignment="Center"
Background="Transparent"
Style="{DynamicResource ComboBoxItemStyle1}">
<StackPanel>
<Label Content="{Binding Name}" Height="32" VerticalContentAlignment="Top"
FontWeight="Bold" Foreground="#FFFEF9F9" AllowDrop="True" />
<TextBlock Text="{Binding Description}"
Foreground="#FF80BBD2"
Padding="5,0,0,10"
FontStyle="Italic" />
</StackPanel>
</ComboBoxItem>
</DataTemplate>
In this case, the Label and the TextBlock both overlap the clickable area for the ComboBoxItem. How do I ignore and/or pass a click through to the ComboBoxItem when I click one of its child controls?
Just set the IsHitTestVisible property to false for those elements:
<DataTemplate x:Key="ProjectsDataItemTemplate">
<ComboBoxItem x:Name="ProjectComboBox"
Opacity="1"
HorizontalAlignment="Stretch"
Foreground="#FF80BBD2"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Background="Transparent"
Style="{DynamicResource ComboBoxItemStyle1}">
<StackPanel>
<Label IsHitTestVisible="False"
Content="{Binding Name}"
Height="32"
VerticalContentAlignment="Top"
FontWeight="Bold"
Foreground="#FFFEF9F9"
AllowDrop="True" />
<TextBlock IsHitTestVisible="False"
Text="{Binding Description}"
Foreground="#FF80BBD2"
Padding="5,0,0,10"
FontStyle="Italic" />
</StackPanel>
</ComboBoxItem>
</DataTemplate>

Resources