How do i make a clickable listbox? - c#

i have a list of users that are bound to a listbox(image and the name of the user) and i want to render this lisbox clickable so whnever i click on a user's image i will be redirected
to his account.
this is the user control that displays the users:
<UserControl x:Class="Navigateur.Presentation.UserControlWork.ListeEnfControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:conv="clr-namespace:Navigateur.Presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Height="Auto" Width="Auto"
>
<UserControl.Resources>
<conv:ByteArrayToImageConverter x:Key="bytearraytoImageConverter" />
</UserControl.Resources>
<Grid >
<ListBox x:Name="_imageList" Margin="10,10,10,0" IsSynchronizedWithCurrentItem="True" ScrollViewer.HorizontalScrollBarVisibility="Visible" VerticalAlignment="Top" Height="250" BorderThickness="0" MouseLeftButtonDown="Click_Kid" >
<ListBox.ItemTemplate>
<DataTemplate DataType="Enfant">
<Border CornerRadius="30">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Grid.Row="0" x:Name="image" Source="{Binding avatar}" Width="50" Height="80"/>
<TextBlock Grid.Row="1" x:Name="nom" Text="{Binding prenom}" VerticalAlignment="Center"/>
</Grid>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>

Use Button in place of Image and override template of Button to give it an Image look, so that you can have clickable image.
<Button Grid.Row="0" Width="50" Height="80">
<Button.Template>
<ControlTemplate>
<Image x:Name="image" Source="{Binding avatar}"/>
</ControlTemplate>
</Button.Template>
</Button>
If you are using MVVM, you can bind Command with button OR if want to do in code behind you can hook Click event of button to determine which image is clicked on.

Related

UWP GridView scroll bar never showing up

I have a Page that allow the user to load multiple images thumbnails from his folders.
The number of rows update nicely when the width of the window is changed
The only thing that I could not figure out how to make it work is having the vertical scroll bars, I pretty much tried every settings possible.
At first my root was a stackPanel so I switched to a Grid to see if there would be any difference.
here is my xaml
<Page
x:Class="IMG.Pages.UploadPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:img="using:IMG"
xmlns:local="using:IMG.Pages"
xmlns:Models="using:IMG.Models"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="root">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"
Padding="2"
BorderBrush="Black"
BorderThickness="1"
Orientation="Horizontal">
<Button Click="GetPhoto" Content="get images" />
</StackPanel>
<GridView x:Name="ImageGrid" Width="Auto" Background="LightBlue" Grid.Row="1" Margin="5" Height="Auto"
SizeChanged="ImageGridSizeChanged"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollMode="Disabled">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Horizontal"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemTemplate>
<DataTemplate x:Name="ImgThumbnail" x:DataType="Models:ImageData">
<StackPanel
Width="100"
Height="120"
Margin="5"
AutomationProperties.Name="{x:Bind Hash}">
<StackPanel Margin="1">
<TextBlock Text="{x:Bind File}" />
</StackPanel>
<Image x:Name="thumbIMG" Width="80" Height="100" Stretch="UniformToFill" />
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
At first the gridview is empty, the user click on the button and then in the FileOpenPicker he can choose multiple images and they are added as thumbnail binded to an ObservableList of ImageData
The binding work nicely, I am simply stuck on the scrollbar
I have experienced the same issue and I fixed it by setting the height of the gidview on the fix size instead of auto. And than you can set
ScrollViewer.VerticalScrollBarVisibility = "Visible"
ScrollViewer.VerticalScrollMode = "Enable"

Changing the ContentControl.Content stacks the content on top of each other

I have a MainWindow with a couple of radio buttons, a ContentControl and a button to change the content of ContentControl.
I also have a UserControl1 with a label on it. When I click the button on MainWindow to change the ContentControl.Content to UserControl1, it shows the label on top of the radio buttons I have from MainWindow. How can I change this so it acts like a page and does not stack each control on top of each other?
MainWindow.xaml:
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
Title="Test" WindowStartupLocation="CenterScreen" Width="968" Height="560" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Height="540" Margin="0,10,-6,-19" Width="968">
<StackPanel Height="74" Margin="731,446,0,0" VerticalAlignment="Top" Width="229" Orientation="Horizontal" HorizontalAlignment="Left">
<Button Content="Back" MinWidth="100" Margin="10,20,0,0"/>
<Button Content="Next" MinWidth="100" Margin="10,20,0,0" Click="NextBtnClick"/>
</StackPanel>
<RadioButton x:Name="RadioBtn1" Content="Radio1" HorizontalAlignment="Center" Margin="312,130,95,0" VerticalAlignment="Top" Height="76" Width="561" FontSize="48" FontWeight="Bold" GroupName="1"/>
<RadioButton x:Name="RadioBtn2" Content="Radio2" HorizontalAlignment="Center" Margin="312,232,95,0" VerticalAlignment="Top" Height="76" Width="561" FontSize="48" FontWeight="Bold" GroupName="1"/>
<ContentControl x:Name="contentControl" Grid.Row="1"/>
</Grid>
</Window>
MainWindow.xaml.cs:
private void NextBtnClick(object sender, RoutedEventArgs e)
{
if (RadioBtn2.IsChecked == true)
{
this.contentControl.Content = new UserControl1();
}
}
After clicking the next button, I get the controls from UserControl1 stacked on top of the radio buttons.
I'm quite new to WPF so any help would be greatly appreciated. Navigating through the docs is a nightmare because I'm not sure how to tackle this problem.
You can trying to use Grid panel without defining rows and column definitions. As per your code, you are trying define the panel layout by hardcoded Margin, Width and Height. That's why contorls are rendered on top of each other.
I've changed the Grid code to define the Row Definitions so that controls are stacked on row basis. So when you click on Button the ContentContrl is loaded to last Row so (which is defined as Height="*" via RowDefinition to take the remaining space)
You can read about WPF Panels and Grid layout at internet. This can be a good start.
<Window x:Class="Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
Title="Test" WindowStartupLocation="CenterScreen" Width="968" Height="560" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Margin="10 10 10 10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions?
<StackPanel Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Left">
<Button Content="Back" MinWidth="100" />
<Button Content="Next" MinWidth="100" Click="NextBtnClick"/>
</StackPanel>
<RadioButton Grid.Row="1" x:Name="RadioBtn1" Content="Radio1" HorizontalAlignment="Center" VerticalAlignment="Top" FontWeight="Bold" GroupName="1"/>
<RadioButton Grid.Row="2" x:Name="RadioBtn2" Content="Radio2" HorizontalAlignment="Center" FontSize="48" FontWeight="Bold" GroupName="1"/>
<ContentControl x:Name="contentControl" Grid.Row="3"/>
</Grid>
</Window>

C# WPF - Dockpanel's children collapsed not resizing the other visible childs

I'm sorry if I didn't find any relative post/questions regarding my small annoying issue.
I have a WPF window with a DockPanel (LastChildFill = True) that hosts three controls :
One Button (OK)
One label (Title)
One Border with a listbox in it
What I do is when the test in process is "pass" it has no data to push in the listbox so I make it collapsed and then I would like the Title label to be centered in the available space that is not used by the listbox and its border.
When I have a "fail" or an "error", I have data to put in the listbox and then it is visible and everything is just as expected.
I tried many things before coming here and I lost enough time on this as I need to get other stuff done by the time I'm writing here.
Can anyone point me out how to solve my issue (centering label when listbox+border is collapsed) ?
Here is my xaml code for this window :
<Window x:Class="NI.TestStand.WPFControls.Views.DisplayBannerView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NI.TestStand.WPFControls"
mc:Ignorable="d"
Title="DisplayBanner" x:Name="DisplayBannerMessage" Height="500" Width="800" MinHeight="300" MinWidth="500">
<Window.Resources>
<Style x:Name="BaseWindowFont" TargetType="Window">
<Setter Property="FontFamily" Value="Arial"></Setter>
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</Window.Resources>
<Grid>
<Border BorderBrush="Black" BorderThickness="2">
<DockPanel LastChildFill="True">
<Button
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click"/>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Border>
</Grid>
</Window>
Here are the images that shows a PASS and an ERROR to show the difference.
The PASSED title message in the green lime window should go in the middle of the window as the listbox is collapsed..
Thanks for all your help and time
I would design the whole thing like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="2"
Grid.RowSpan="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToRowSpanConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border Grid.Row="1" BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border"
Visibility="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToVisibilityConverter}}">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
<Button Grid.Row="2"
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click" />
</Grid>
</Border>
</Grid>
There are two bindings to PassErrorBooleanProperty (which I've made up as something you'd use to indicate the result, you might have something else in place for this already), and you'd need two different converters, one for converting to a Visibility, and one for converting to an int (Grid.RowSpan).
When the value is true (Pass), you'd return Visibility.Collapsed and 2 from the converters. When the value is false, you'd return Visibility.Visible and 1.
Let me know if you need more info on the converters, though there is lots of information out there on using IValueConverter to create Boolean to Visibility converters, etc.

WPF How can i make a button in "L" form

I would like my button to have the shape of the letter "L" as in this picture Simple Paint Example. The only examples I can find are if you want the button to be round or like a lemon. I know that I need to use template but how exactly I don't understand.
The Code is in the App.xaml for global using.
<!--#region LButton-->
<ControlTemplate x:Key="LButton" TargetType="Button">
<Grid Width="100" Height="100">
<Border BorderThickness="1" Grid.Row="0" Grid.ColumnSpan="2" BorderBrush="Black" Background="LightGreen">
<TextBlock Text="{TemplateBinding Button.Content}" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="40"/>
</Border>
</Grid>
</ControlTemplate>
<!--#endregion-->
I know i can add CornerRadius="30,30,30,30" that the Button has Rounded Corners.
Thx for your help. Best Regards Shazzar
This can be done by overwriting the Control Template. Here is a very rough example to get you started.
EDIT Updated Path to be L shape
<Button >
<Button.Template>
<ControlTemplate>
<Border>
<Grid>
<Polygon Points="300,200 200,200 200,300 250,300 250,250 300,250" Fill="Purple" />
</Grid>
</Border>
</ControlTemplate>
</Button.Template>
</Button>
Maybe this can help you:
<UserControl x:Class="Test.LButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Test"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Name="upButton" Grid.ColumnSpan="3" Grid.RowSpan="1" Margin="0" BorderThickness="0"></Button>
<Button Grid.Row="1" Grid.ColumnSpan="2" Margin="0" BorderThickness="0" Background="{Binding Background, ElementName=upButton}"></Button>
</Grid>
</UserControl>
I created two buttons one is the up part and other for the down part, then I used binding between the two buttons in order to get the same style.
I think that you can not create an LButton using only one button.

ScrollViewer does not scroll Image WPF

I have an image that is bigger than it's window container and it is placed in a ScrollViewer, however, the image does not scroll at all. I've tried putting the image in a container with no luck. What settings am I missing here? (I copied the code straight from MS, but they have it wrong)
Here's the code:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:h="http://helixtoolkit.codeplex.com" x:Class="TileLayout"
Title="TileLayout" Height="1000" Width="845" WindowStartupLocation="CenterScreen" WindowStyle="ThreeDBorderWindow">
<StackPanel HorizontalAlignment="center" VerticalAlignment="Top">
<StackPanel Orientation="Horizontal" >
<TextBox x:Name="txtSourceFilePath" Width="500" Margin="10" Height="22" TextChanged="TextBox_TextChanged" Text="E:\projects\Test3D\SavedSnapshots\snapshot.png"/>
<Button x:Name="btnPickFile" Width="100" Margin="0,10,10,10" Content="Pick File" ></Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<Image x:Name="imgFinal" Source="SteelMotion_chevron2.png"/>
</ScrollViewer>
</StackPanel>
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:h="http://helixtoolkit.codeplex.com" x:Class="TileLayout"
Title="TileLayout" Height="1000" Width="845" WindowStartupLocation="CenterScreen" WindowStyle="ThreeDBorderWindow">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Height="50" HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="0">
<TextBox x:Name="txtSourceFilePath" Width="500" Margin="10" Height="22" TextChanged="TextBox_TextChanged" Text=""/>
<Button x:Name="btnPickFile" Width="100" Margin="0,10,10,10" Content="Pick File" ></Button>
</StackPanel>
<ScrollViewer VerticalScrollBarVisibility="Auto" Grid.Row="1" >
<Image x:Name="imgFinal" Source="SteelMotion_chevron2.png" Width="768" Height="1408"/>
</ScrollViewer>
</Grid>
You need to specify the size of the ScrollViewer.
In this case ScrollViewer and Image are same size, so the scroll bar does not show.

Categories

Resources