WPF VB.NET ListView DataTemplate change - wpf

I'm trying to replicate the functionality you have in Windows Explorer for changing layout via a series of layout toggle buttons. Layouts such as "List", "Details", "Tiles", etc etc.
I've found several other posts on this, but none have really answered the problem for me, plus they are all C# and I've not used C# so trying to decipher the answers is extremely frustrating.
This is what I've got so far - I'm starting with just List and Details while trying to get is working, but plan to add in Tiles and Content as well:
XAML:
<Window.Resources>
<DataTemplate x:Key="List_Template">
<Grid...>
</DataTemplate>
<DataTemplate x:Key="Details_Template">
<Grid...>
</DataTemplate>
<DataTemplate x:Key="SelectedItem_Template">
<Grid...>
</DataTemplate>
<Style TargetType="{x:Type ListBoxItem}" x:Key="List_ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource List_Template}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedItem_Template}" />
</Trigger>
</Style.Triggers>
</Style>
<Style TargetType="{x:Type ListBoxItem}" x:Key="Details_ContainerStyle">
<Setter Property="ContentTemplate" Value="{StaticResource Details_Template}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedItem_Template}" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
I'm using Radio buttons to change the layout for simplicity at the moment, but will at some point change them to buttons that resemble the Windows Explorer options:
<Grid Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<RadioButton x:Name="List_RadioButton" Content="List" Grid.Row="0" Grid.Column="0" Margin="8,0,8,0" VerticalAlignment="Center"
Foreground="{DynamicResource LightFont_Colour}"
IsChecked="True"/>
<RadioButton x:Name="Details_RadioButton" Content="Details" Grid.Row="0" Grid.Column="1" Margin="8,0,8,0" VerticalAlignment="Center"
Foreground="{DynamicResource LightFont_Colour}"
IsChecked="False"/>
</Grid>
The ListView is Data Bound to a view from SQL Server. by default i want it to be on List layout if not manually set by the user:
<Grid x:Name="Grid_Body" Grid.Row="3" Grid.ColumnSpan="2" >
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<ListView x:Name="DataList_ListView"
Grid.Row="0" SelectionMode="Single" SelectedValuePath="ID"
IsSynchronizedWithCurrentItem="True"
DataContext="{Binding}"
ItemContainerStyle="{StaticResource List_ContainerStyle}"
Background="{DynamicResource WhiteBackground_90Transparent}" Margin="0,0,0,0">
</ListView>
</Grid>
VB.NET - I've been trying to find a way to change the ItemContainerStyle in code when i hit the RadioButton to change to details layout or back to list layout. The below does not work and was partially lifted from another stackoverflow post:
Private Sub List_RadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles List_RadioButton.Checked
CaseList_ListView.ItemContainerStyle = DirectCast(Resources("List_ContainerStyle"), System.Windows.Style)
End Sub
Private Sub Details_RadioButton_Checked(sender As Object, e As RoutedEventArgs) Handles Details_RadioButton.Checked
CaseList_ListView.ItemContainerStyle = DirectCast(Resources("Details_ContainerStyle"), System.Windows.Style)
End Sub
Any help would be appreciated.

Related

XAML displaying system message when using datatemplate

When trying to create a simple datatemplate to change the visibility of a text block from collapsed to visible my window is displaying the text;
System.windows.DataTemplate
And nothing else.
My code;
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Visibility="Collapsed" Name="one" Grid.Row="0" Grid.Column="0">One</TextBlock>
<TextBlock Visibility="Collapsed" Name="two" Grid.Row="0" Grid.Column="0">Two</TextBlock>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Data.isCorrect}" Value="true">
<Setter TargetName="one" Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Data.isCorrect}" Value="false">
<Setter TargetName="two" Property="Visibility" Value="Visible"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
isCorrect is simple declared within the Xaml.cs file as;
public Boolean isCorrect = true;
An additional question if I'm allowed to whilst I'm here. As far as I understand the use of;
Data.isCorrect
Gets the value from the cs file, but is there any documentation about this as I've been unable to find anything to do with the Data keyboard as I've simply picked it up through tutorials.

Silverlight Style : custom style based on custom style

Someone has done a custom style for the buttons of the application. Now I want to create a custom style based on this custom style. For example I want to make a "close button" that I want to reuse all other the application. I tried this :
<Style x:Key="GlassButtonClose" TargetType="Button" BasedOn="{StaticResource GlassButton}">
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Grid.Row="0" Source="/Balisage;component/Images/Close.png" Width="24" Height="24" />
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding Source={StaticResource LocCommonStrings}, Path=ButtonLabelClose}" Margin="0" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
But this doesn't keep the GlassButton settings. How can I just extend the settings, keeping the existing ones ?
Thanks for your help
Based on the shown template and your answer in the comments it looks like you only need to have a spacific GlassButton with a fixed icon and text. And you want to use this button without the need to specify its content again and again.
Solution:
Prepare your own type GlassStyleCloseButton.
public class GlassStyleCloseButton : Button
{
public GlassStyleCloseButton() {
DefaultStyleKey = typeof(GlassStyleCloseButton); }
}
and a style for the new type (can be placed in app.xaml or generic.xaml):
<Style TargetType="GlassStyleCloseButton" BasedOn="{StaticResource GlassButton}">
<Setter Property="Content" Value="{Binding Path=ButtonLabelClose,
Source={StaticResource LocCommonStrings}}"/>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image
Source="/Balisage;component/Images/Close.png"
Width="24"
Height="24"/>
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{TemplateBinding Content}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
and you can use it like this:
<SomewhereInMyApp>
...
<GlassStyleCloseButton/>
</SomewhereInMyApp>

WPF ListBox Item collapse datatrigger not working

I have a listbox and all I want to do is collapse the listboxitem based on a boolean property of my SelectedItem.
The IsVisible property on my client Model implements the NotifyPropertyChanged event.
Overview - I have a list of clients which users can do CRUDs on. When they delete, I set a boolean property on the Model which my VM exposes to the View. This should then only hide the 'deleted' row from the list. During a flush to db I CRUD based on the mode of the model.
<ListBox Name="listClients"
Grid.Column="1" Grid.Row="1"
Margin="0" BorderThickness="0"
Height="auto"
Style="{StaticResource BumListBox}"
SelectionMode="Extended"
ItemsSource="{Binding Path=ClientList}"
SelectedItem="{Binding SelectedClient, Mode=TwoWay}"
Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="50"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding ClientNo}" Foreground="White" FontSize="{StaticResource HeaderFontSize}" VerticalAlignment="Center" />
<TextBlock Grid.Column="1" Text="{Binding ClientDesc}" Foreground="White" FontSize="{StaticResource SubHeaderFontSize}" FontWeight="Light" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Code behind to jippo MVVM process:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
if (_cvm.SelectedClient != null)
{
_cvm.SelectedClient.IsVisible = !_cvm.SelectedClient.IsVisible;
_cvm.CurrentSelectedIsVisible = _cvm.SelectedClient.IsVisible; //<- another option to bind to
}
}
I've tried the these suggestions here and here or something similar but I just can't get to hide the items.
Any help in the right direction would be great, cheers.
Edit
I've tried Blam's suggestion below like this but still unable to hide the items:
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Visibility" Value="{Binding Path=CurrentIsVisible, Converter={StaticResource b2v}}" />
</Style>
You will need to set up a converter if you are returning true/false but there is a system converter for that
Move it up to Resources
I have know I have used it this way
<ListBox x:Name="lb" ItemsSource="{Binding}" DisplayMemberPath="Text">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Visibility" Value="{Binding Path=Vis}" />
</Style>
</ListBox.Resources>
</ListBox>
This was rather frustrating and the solution so simple. My client model with IsVisible is in a dll and the NotifyPropertyChanged() changes were never built to update the reference in my project..so the binding never happened. These late nights are taking their toll.

Show "pop up window" when is mouser over listBox item

I bind observable collection on listBox. I have data tempate on listbox item. It consit one image control and som textBlock.
If is mouse over on some listBox item I would like achieve this behavior:
Show PopUp/ToolTip (some "rectangle" with controls) and bind values from listBox current item.
And on textBox in item data template I have style, I would like change color of text in textBlock, for example from black to green.
Style is here:
<Style x:Key="FriedNickStyle" TargetType="TextBlock">
<Setter Property="Margin" Value="2,2,2,2"/>
<Setter Property="FontSize" Value="13"/>
<Setter Property="FontWeight" Value="Medium"/>
<Setter Property="Foreground" Value="Black"/>
</Style>
Sory for my english, I have problem how describe this behavior correct. I try many thing but any of them doesn’t work good.
Here is it my style:
<DataTemplate x:Key="FriendListBoxItemTemplate">
<Grid Name="RootLayout">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<Image Margin="4,4,4,2" Grid.Column="0">
<Image.Source >
<MultiBinding Converter="{StaticResource avatarConverter}">
<Binding Path="ProfilePhoto"></Binding>
<Binding Path="StatusInfo.IsLogged"></Binding>
</MultiBinding>
</Image.Source>
</Image>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding Path=Nick}"
Style="{StaticResource FriedNickStyle}"
Grid.Column="0" Grid.Row="0">
</TextBlock>
</Grid>
</Grid>
<DataTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--SHOW SOME POP UP WINDOW and bind properties from ITEM (VALUE)-->
<!--Change color of textBlock-->
</Trigger>
</DataTemplate.Triggers>
</DataTemplate>
Thank everybody who help me.
Well, I found this turorial, this article, by the MSDN and another stack overflow's question.
Basically, here's how:
<Popup Margin="10,10,0,13"
Name="Popup1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="194"
Height="200"
IsOpen="True"> // change this to open it
<TextBlock Name="McTextBlock" Background="LightBlue" >
This is popup text
</TextBlock>

How do I Show/Hide a Grid Row and Grid Splitter based on a Toggle Button?

Currently I have a toggle button that is bound to a boolean property (DualLayout) in my code behind. When the boolean is set to True, then I want my second row in my grid (and grid splitter) to hide and have the first row take up the entire space of the grid. Once the boolean is set to False, I want the grid splitter and bottom row to appear.
Here is a snippet of my xaml
<ToggleButton Name="toggleLayout" Margin="66,1,0,1" Width="25" HorizontalAlignment="Left" IsChecked="{Binding DualLayout}" Checked="toggleLayout_Clicked" Unchecked="toggleLayout_Clicked">
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type ToggleButton}">
<Image Source="Images/PlayHS.png"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Receive and Transmit Windows Split."/>
</Trigger>
<Trigger Property="IsChecked" Value="false">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate DataType="{x:Type ToggleButton}">
<Image Source="Images/PauseHS.png"/>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="ToolTip" Value="Receive and Transmit Windows Combined."/>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<Grid x:Name="transmissionsGrid" Margin="0,28,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*" MinHeight="100" />
</Grid.RowDefinitions>
<transmission:TransmissionsControl x:Name="transmissionsReceive" TransmissionType="Receive" Margin="0,0,0,5" />
<GridSplitter Name="gridSplitter1" Grid.Row="0" Background="White" Cursor="SizeNS" Height="4" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Foreground="Firebrick" />
<transmission:TransmissionsControl x:Name="transmissionsTransmit" TransmissionType="Transmit" Grid.Row="1" />
</Grid>
This is untested, but I believe it should work.
First, if you want your first row to take up the whole space, you'll want to define your RowDefinitions as
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto" /> <!-- Edit: Removed MinHeight="100" -->
</Grid.RowDefinitions>
For showing/hiding the controls, you'll need to bind their Visibility property either to your DualLayout property (if the class properly implements INotifyPropertyChanged), or (perhaps more simply) to the IsChecked property of the ToggleButton.
For instance (the same applies to the GridSplitter):
<!-- EDIT: Added MinHeight="100" here instead -->
<transmission:TransmissionsControl x:Name="transmissionsTransmit"
TransmissionType="Transmit"
Grid.Row="1"
MinHeight="100"
Visibility={Binding ElementName=toggleLayout,
Path=IsChecked,
Converter={StaticResource boolToVis}}" />
At some level above the controls in question (here I am doing it at the window level) you need to add built-in BooleanToVisibilityConverter resource:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="boolToVis" />
</Window.Resources>

Resources