How to delete a Template on a Button click - c#

i have ControlTemplate, which is used as a resource inside a ListBox, i am trying to delete the template i.e remove it totally from ListBox on a Button click
here is the code for template
<ControlTemplate x:Key="tasktemplate1">
<Canvas Height="50" Width="850">
<Label Content="{Binding XPath=task[1]/name}" Height="30" Width="170" Canvas.Top="10" Canvas.Left="150" Background="LightGray">
</Label>
<TextBox Height="30" Width="120" Canvas.Top="10" Canvas.Left="370" Background="AliceBlue"></TextBox>
<Label Canvas.Left="500" Canvas.Top="10">$</Label>
<Button Click="deletebuttonclick" Canvas.Top="12" Height="10" Width="30" Canvas.Left="600" ></Button>
</Canvas>
</ControlTemplate>
here is the code for ListBox
<TabItem>
<Canvas Height="700" Width="850">
<ListBox x:Name="listBox" Height="700" Width="850">
<ListBoxItem DataContext="{Binding Source={StaticResource TaskList}}" Template="{StaticResource tasktemplate1}"/>
</ListBox>
</Canvas>
</TabItem>
and the code behind is for the Button click
private void deletebuttonclick(object sender,RoutedEventArgs e)
{
var r=listBox.FindResource("tasktemplate1");
listBox.Items.Remove(r);
}
where am i going wrong,help needed,thanx.

ControlTemplate is just visual representation of control that how it will look like.
So, you need to remove the item (ListBoxItem) from the Items collection and not Template. Since templated control is removed, template automatically will be removed.
private void deletebuttonclick(object sender,RoutedEventArgs e)
{
listBox.Items.RemoveAt(0);
// listBox.Items.Clear(); OR in case want to clear all listBoxItems, use Clear
}

Related

Hiding/Showing a UserControl WPF

I am building a WPF MVVM application.
What I have:
I have a ShellWindow which looks like this:
It is composed by 2 rows:
1: the hamburger menu (not important) with Height="*"
2: the console with Height="100"
The console is a UserControl:
<UserControl
//namespaces>
<Grid Name="LoggingGrid" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Margin="{StaticResource SmallLeftMargin}">
<Button
x:Name="CollapseBtn"
Width="25"
Height="25"
Click="CollapseBtn_Click"
Content="▲">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Ellipse Fill="White" />
<ContentPresenter
HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="{TemplateBinding Content}" />
</Grid>
</ControlTemplate>
</Button.Template>
</Button>
<StackPanel Margin="5,0,0,0" Orientation="Horizontal">
<Image
Height="25"
Source="/Images/console-icon.png"
Visibility="Visible" />
<Label
Content="Console"
FontSize="16"
Foreground="White" />
</StackPanel>
</TextBlock>
<Border Grid.Row="1">
<ListView
x:Name="LoggingList"
Margin="5"
Background="Black"
BorderThickness="0"
Foreground="White"
ItemsSource="{Binding Logs, UpdateSourceTrigger=PropertyChanged}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</Border>
</Grid>
</UserControl>
I have omitted the non-important things.
What I want to do:
Whenever the user clicks on the button, the console should collapse and look something like this:
The arrow is also changed.
How can I implement this? What is the best approach using MVVM?
What I have tried:
I have tried using a button click event handler in the code behind - CollapseBtn_Click, just to see what will happen:
private void CollapseBtn_Click(object sender, System.Windows.RoutedEventArgs e)
{
LoggingGrid.Visibility = System.Windows.Visibility.Hidden;
}
Apparently it removes the user control and leaves a white background where it used to be.
Instead of setting the Visibility of the whole LoggingGrid to Hidden, you should set the Visibility of the LoggingList to Collapsed. (For the difference between Hidden and Collapsed, see here: Difference between Visibility.Collapsed and Visibility.Hidden).
Depending on your layout in the ShellWindow you probably have to adjust your row height configuration in the UserControl such that the collapsed LoggingGrid leads to a row with a height of zero.
Regarding MVVM the best approach would be to bind the Button to a bool property ConsoleVisible on your ViewModel such that clicking the button toggles the property between true and false. The styling of the button can be bound to the same property. For the LoggingList Visibility you could use a Binding with a BooleanToVisibilityConverter on the same property.

WPF find clicked button closest parent (TabItem) and close it

I am wondering whether there is a better simpler way rewrite the following code find the closest parent which is a TabItem and remove it from the TabControl.
I have a TabControl where I add new TabItems dynamically. I assign a HeaderTemplate to each tab which looks like this;
<DataTemplate x:Key="AttorneyTabHeader">
<StackPanel Orientation="Horizontal">
<TextBlock Text="THE title" Margin="2,0,0,0" FontSize="16" VerticalAlignment="Center" />
<Button Width="Auto" UseLayoutRounding="False" BorderBrush="Transparent" Background="Transparent" Click="CloseAttorneysTabButtonClick">
<Image Source="/images/close-cross-thin-circular-button/close-cross-thin-circular-button16.png" Height="16"></Image>
</Button>
</StackPanel>
</DataTemplate>
The header has a close button and I would like to close the TabItem whenever the button is clicked. My click handler looks like this;
public void CloseAttorneysTabButtonClick(object sender, RoutedEventArgs e)
{
TabItem this_tab = (TabItem)((Button)sender).Parent.GetParentObject().GetParentObject().GetParentObject().GetParentObject().GetParentObject().GetParentObject();
AttorneysTabControl.Items.Remove(this_tab);
}
I am wondering whether there is a better way to rewrite this because now I am depending on getting the parent over and over again suppose I change the button and forget changing the handler.
There's probably a few ways you can handle it, but the simplest is likely to bind to the TabItem in the Tag property for the Button so that you can use it in your event handler.
<DataTemplate x:Key="TabHeaderTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="The Title" Margin="2 0 0 0" FontSize="16" VerticalAlignment="Center" />
<Button Width="Auto" UseLayoutRounding="False"
BorderBrush="Transparent" Background="Transparent"
Tag="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TabItem}}, Mode=OneWay}"
Click="Button_Click">
<Image Source="images/close.png" Height="16" />
</Button>
</StackPanel>
</DataTemplate>
Now your event handler can be relatively simple, and doesn't need to know as much as it does in your example.
void Button_Click(object sender, RoutedEventArgs e)
{
if (sender is Button button && button.Tag is TabItem item) {
var tabControl = (TabControl)item.Parent;
tabControl.Items.Remove(item);
}
}

UWP - Using ListView inside SplitView.Pane

I have currently a hamburger menu for my UWP app build using SplitView.Pane.
The problem with this implementation is, only the "Symbol" or <Button> element is actually clickable, not the text beside it in the pane.
I read on this forum and other tutorials that some have solved this problem by using a ListView, but in the GitHub samples I see that they have done this with CS instead of a simpler XAML implementation.
Does anybody know how to do this in the XAML directly?
ListView is an ItemsControl, so it can contain a collection of items of any type. To populate the view, add items to the Items collection, or set the ItemsSource property to a data source.
For more info, see ListView.
A common scenario is to bind to a collection of business objects. In C# and Visual Basic, the generic ObservableCollection class is a good collection choice for data binding. For more info, see Binding to a collection of items.
But, we can also add ListViewItem to the ListView in XAML code.
For example:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<RelativePanel>
<Button FontFamily="Segoe MDL2 Assets" FontSize="36" Content="" Click="Button_Click"></Button>
</RelativePanel>
<SplitView Grid.Row="1" Name="mySplitView" DisplayMode="CompactOverlay" OpenPaneLength="200" CompactPaneLength="56" HorizontalAlignment="Left">
<SplitView.Pane>
<ListView Name="MyListView" SelectionChanged="ListView_SelectionChanged">
<ListView.Items>
<ListViewItem Name="FristItem">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="36" Text=""></TextBlock>
<TextBlock Margin="20,0,0,0" Text="Click" FontSize="36"></TextBlock>
</StackPanel>
</ListViewItem>
<ListViewItem Name="SecondItem">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="36" Text=""></TextBlock>
<TextBlock Margin="20,0,0,0" Text="Click" FontSize="36"></TextBlock>
</StackPanel>
</ListViewItem>
</ListView.Items>
</ListView>
</SplitView.Pane>
<SplitView.Content>
<Frame Name="MyFrame"></Frame>
</SplitView.Content>
</SplitView>
</Grid>
In code behind:
private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (MyListView.SelectedItem.Equals(FristItem))
{
}
else if (MyListView.SelectedItem.Equals(SecondItem))
{
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
mySplitView.IsPaneOpen = !mySplitView.IsPaneOpen;
}
Well there are some xaml examples of this available on GitHub...
Here is one: https://github.com/AppCreativity/Kliva/blob/master/src/Kliva/Controls/SidePaneControl.xaml#L25
And here is another one:
https://github.com/JustinXinLiu/SwipeableSplitView/blob/master/GestureDemo/Shell.xaml#L103
In short, you just add the ListView in your Pane part of the SplitView and take note of the DataTemplates used to be sure that you have an icon and text.
Like this:
https://github.com/AppCreativity/Kliva/blob/c36d65058c4c35f0a3d2c7c886df81ba5ecfb31b/src/Kliva/XAMLResources/DataTemplates.xaml#L410

C# XAML Listbox collapse when clicked

I'm new in XAML for Windows Phone 8.1 and have some troubles with
making a Stackpanel clickable
collapse Item, when clicked
My work so far looks like that:
And the Code to that (please correct me, if there are major flaws):
<Border CornerRadius="15" Background="#FF595656" Margin="0" Grid.ColumnSpan="2" Height="80">
<StackPanel Orientation="Horizontal">
<StackPanel Width="20" HorizontalAlignment="Left" VerticalAlignment="Top" />
<StackPanel HorizontalAlignment="Left" Height="80" Margin="0,0,0,0" VerticalAlignment="Center" Width="51">
<Image HorizontalAlignment="Left" Height="51" Margin="0,15,0,0" Width="51" Source="Assets/fish.png" Stretch="Fill" RenderTransformOrigin="2.307,0.881" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Width="10" HorizontalAlignment="Left" VerticalAlignment="Top" />
<StackPanel HorizontalAlignment="Left" Height="80" Margin="0" VerticalAlignment="Top" Width="310">
<TextBlock HorizontalAlignment="Left" Height="25" Margin="0,20,0,0" TextWrapping="Wrap" Text="Entry 1" Width="310" VerticalAlignment="Top" FontSize="18" Foreground="Black" FontWeight="Bold"/>
<TextBlock HorizontalAlignment="Left" Height="17" Margin="0" TextWrapping="Wrap" Text="Short description Entry 1" Width="310" VerticalAlignment="Top" Foreground="#FF0097FF"/>
</StackPanel>
</StackPanel>
</Border>
This code will later be wrapped inside a ListBox with Image, Entry 1 and the short description being bound:
<ListBox x:Name="ListBox1" Margin="0"
Width="400" Height="200" HorizontalAlignment="Left"
ItemsSource="{Binding}" Grid.Row="1" VerticalAlignment="Top" Grid.ColumnSpan="2" >
<ListBox.ItemTemplate>
<DataTemplate>
// the code above
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So my question is:
How can I make a nice looking expansion/collapse of each Item in the ListBox, whenever I click on it?
Thank you very much in advance.
The real question is here is what do you want it to collapse to? There are too many possible ways to collapse some visual data item. Do you just want to change the height of the item or do you want some fancy animation that collapse some property?
If the height is what you're looking for it's pretty easy. Just attach an Tap Event on that Border of yours. On a sidenote, you probably want to edit the ItemContainerStyle to have <Setter Property="HorizontalContentAlignment" Value="Stretch"/> so the Listbox will stretch across the screen, otherwise imho it's un-useable.
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Red" BorderThickness="0,1" Tap="Border_Tap">
<StackPanel>
<!--- rest of template --->
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
Then calculate the Minimum height you want to show (make sure it's actually useable, meaning... I can Tap on it again to show the whole thing without using a Mag Glass).
private void Border_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
int minHeight = 40; // change to whatever you want
Border b = sender as Border;
if (b.ActualHeight > minHeight)
{
b.Height = minHeight;
}
else
{
b.Height = double.NaN; // this will change the height back to Auto, showing everything
}
}
Code In Action
This is just a quick solution to your question. Some people on here would rather have you create a StoryBoard Animation on the Height Property of the Selected state in the VisualStateManager. If you reword or create a new question explicitly stating you want a VisualStateManager solution, I will provide you one as well. Good luck.

ListView disable right tapped selection style

I am trying to disable the right click functionality of my items inside a list view. I have tried handling the RightTapped event and setting the e.handled value to true. This has covered most of the list view's area however if I right click on the borders of the list view item, this selection style is still applied. I want the user to still be able to use the left click and apply the list selected styling. It is just the right click I want to disable.
Here is what I have tried so far:
<ListView
ItemsSource="{Binding MyItems}"
ItemClick="OnItemClicked"
IsItemClickEnabled="True"
SelectionMode="Multiple"
CanDragItems="True"
DragItemsStarting="OnDragItemsStarting"
RightTapped="OnRightTapped"
IsRightTapEnabled="False">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Margin" Value="-1,3,-1,0" />
<Setter Property="IsRightTapEnabled" Value="False"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent" RightTapped="OnRightTapped" HorizontalAlignment="Left" Height="100" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding ImagePath}" Width="55" Height="55" Margin="0,0,0,1"/>
<Image Margin="20,0,0,22" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left" Width="20" Height="20" Source="smallImage.png"/>
<StackPanel VerticalAlignment="Center" Margin="30,0,0,0" Grid.Column="1">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}" Foreground="{Binding IsOnline, Converter={StaticResource BooleanToColorConverter}}" Style="{StaticResource BaseTextBlockStyle}" FontSize="20" Height="60"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here is the code for the RightTapped handler:
private void OnRightTapped(object sender, RightTappedRoutedEventArgs e)
{
e.Handled = true;
}
Edit: When I click on the borders of an Item in the ListView the OnRightTapped event is not being fired. What could be swallowing this event?
By playing with the background colors of the items inside my ListView.ItemTemplate, I found that my TextBlock was not covering the whole area of the row. By setting the Column width to the exact size of the ListView and setting the RightTapped event handler on this Grid I was able to cover all areas of right clicking. I still do not know why the RightTapped handler was not being fired for the ListView itself but this was a sufficient solution for what I needed.

Categories

Resources