Toggle Button inside a canvas - xaml

I have a canvas object in my xaml that has a togglebutton and two textblocks, like this.
<ListBox.ItemTemplate>
<DataTemplate >
<Canvas HorizontalAlignment="Right" VerticalAlignment="Top" Width="485"
Margin="-15,0,-15,80" Visibility="Visible"
MouseLeftButtonUp="MandantenStackPanel_MouseLeftButtonDown">
<ToggleButton Name="FavToggle" Checked="FavChecked" Unchecked="FavUnchecked"
Style="{StaticResource CustomToggleButtonStyle}"
Foreground ="White" BorderBrush="Red" HorizontalAlignment="Left"
Canvas.Left="0" Canvas.Top="0">
<ImageBrush ImageSource="/Icons/favs.png" Stretch="UniformToFill" >
</ImageBrush>
</ToggleButton>
<TextBlock Text="{Binding MandantenNummer}" FontSize="24"
TextWrapping="Wrap" Canvas.Left="90" Canvas.Top="20"/>
<TextBlock Text="{Binding MandantenBezeichnung}" FontSize="24"
TextWrapping="Wrap" Canvas.Left="90" Canvas.Top="50"/>
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
In my .cs i am binding a collection item to that listbox that also has a boolean called isFavorite that i'd like to toggle with my togglebutton. How can i access the data context from the canvas from inside my toggle event handlers? I tried it like i did it like i do it when you click on the textbox:
private void FavChecked(object sender, EventArgs e)
{
ClassX x = (sender as Canvas).DataContext as Class x;
x.isFavorite = true;
}
but that of course doesn't work cause my sender is the togglebutton and not the canvas. Can i access the canvas from here?

The sender is ToggleButton and not Canvas because that is the control on which you attached that event handler.
Also, DataContext is set recursively so ToggleButton inherits the same data context the parent has.

Related

Is there a way to change the parent content for a popup in WinUI3?

In WinUI3 it seems that you are unable to modify the duration of a tooltip (similar to how WPF allowed a duration change with the ToolTipService.ShowDuration).
As such, I'm attempting to replicate the behavior using a Popup control such that the Popup will remain visible as long as the mouse is hovered over an element (utilizing the element's OnPointerEntered / OnPointerExited events to modify the IsOpen property of the Popup).
This displays the Popup correctly, however in my case the Popup exists inside a Grid which is inside the ListView.ItemTemplate for a ListView. ala:
<ListView>
<DataTemplate>
<Grid>
<TextBlock/>
<Popup/>
</Grid>
</DataTemplate>
</ListView>
Thus the popup only overlays the <Grid>, but still gets clipped within the region of the DataTemplate.
I'd like to have the popup overlay the <ListView> itself instead - is there a way to specify which content the popup will overlay such that it will overlay the <ListView>?
Or even better - to have it overlay all elements of the Window (replicating the placement of a tooltip?)
Is there a way to change the parent content for a popup in WinUI3?
Sure, you could place Popup at same level as ListView in current page. And listen ListView item PointerEntered and PointerExited event then pass current item datacontext to popup control.
Xaml
<ListView
Margin="0,10,0,45"
ItemsSource="{x:Bind Items}"
Visibility="Visible">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Orientation="Vertical"
PointerEntered="StackPanel_PointerEntered"
PointerExited="StackPanel_PointerExited">
<TextBlock x:Name="Id" Text="{Binding ID}" />
<TextBox
x:Name="FirstName"
GettingFocus="FirstName_GettingFocus"
Text="{Binding FirstName}" />
<TextBox x:Name="LastName" Text="{Binding LastName}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Popup
x:Name="PopupTip"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Popup.ChildTransitions>
<TransitionCollection>
<PaneThemeTransition Edge="Bottom" />
</TransitionCollection>
</Popup.ChildTransitions>
<StackPanel
Width="150"
Height="80"
Background="LightGray"
CornerRadius="4">
<TextBlock
x:Name="InfoLabel"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding ID}" />
</StackPanel>
</Popup>
Code behind
private void StackPanel_PointerEntered(object sender, PointerRoutedEventArgs e)
{
var ItemDataContext = (sender as FrameworkElement).DataContext;
PopupTip.DataContext = ItemDataContext;
PopupTip.IsOpen = true;
}
private void StackPanel_PointerExited(object sender, PointerRoutedEventArgs e)
{
PopupTip.DataContext = null;
PopupTip.IsOpen = false;
}

Changing TextWrapping property of a TextBlock inside a GridView

I have a GridView with a TextBlock and a Button. For now, the MinWidth of the GridView's DataTemplate is fixed. The TextWrapping property of the TextBlock ss set to Wrap.
It looks like
the last DataTemplate has more text to show ( wrapping is ON ).
What I want to do is, if I tap on a text block and it has more text to show then it will expand ( in height ) to show the full text. For this, I thought to toggle its TextWrapping property on tap. But it doesn't seem to work this way.
Here's my XAML:
<GridView Name="TagsGridView"
ItemsSource="{x:Bind TagsList, Mode=OneWay}"
SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate x:DataType="x:String">
<Grid Background="#1A503E"
MinWidth="150">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind}"
Grid.Column="0"
Height="Auto"
TextTrimming="CharacterEllipsis"
TextWrapping="Wrap"
VerticalAlignment="Center"
Foreground="White"
Padding="10"
Tapped="TextBlock_Tapped"/>
<Button Content=""
Name="btnTagDelete"
Click="btnTagDelete_Click"
Foreground="White"
Grid.Column="1"
Width="40"
Height="40"
FontFamily="Segoe MDL2 Assets"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
And here's my tapped event:
private void TextBlock_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
var textBlock = sender as TextBlock;
if (textBlock.TextWrapping == TextWrapping.Wrap) textBlock.TextWrapping = TextWrapping.NoWrap;
else textBlock.TextWrapping = TextWrapping.Wrap;
}
This causes the textblock to show some more text but doesn't change the height due to which all the text is not shown. I also tried to increase the height of TextBlock arbitrarily like this:
private void TextBlock_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
var textBlock = sender as TextBlock;
textBlock.Height = 1000;
}
Doing this does increase the height of the template by hardly 20 (unit) but then the Text inside the TextBlock becomes blank.
What is the correct way to achieve what I want?

Binding ObservbleCollection to Combo box in XAML - Windows phone

I tried to bind an ObservableCollection variable to a ComboBox in the XAML. The data is not binding.
XAML File
<ComboBox x:Name="cmbCity" Height="44" Width="150" Grid.Row="4"
ItemsSource="{Binding}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="5" Text="{Binding lstCity}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Code behind (After navigating to another page)
protected override void OnNavigatedTo(NavigationEventArgs e)
{
UserInfo userInfo = new UserInfo();
userInfo.UserName = "Gayathri";
userInfo.Country = "India";
userInfo.State = "TN";
ObservableCollection<string> cityInfo = new ObservableCollection<string>();
cityInfo.Add("Chennai");
cityInfo.Add("Cuddalore");
cityInfo.Add("Pondicherry");
cityInfo.Add("Villupuram");
userInfo.lstCity = cityInfo;
this.DataContext = userInfo;
}
Here I am passing values in the DataContext. The data is getting bound to the textbox but not the Combobox.
Output:
You're bindings are slightly wrong.
They should be like this:
<ComboBox x:Name="cmbCity" Height="44" Width="150" Grid.Row="4"
ItemsSource="{Binding lstCity}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Margin="5" Text="{Binding}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
(I've moved the reference to lstCity)
Previously you were binding the whole DataContext to the ComboBox and then each TextBlock to the Collection of strings.
You need to bind the ItemsSource of the ComboBox to the collection and then each TextBlock should contain one of the strings.

How to create tabs in windows phone 8

I'm a beginner on windows phone 8 developpement, and I need to create a tabs system ( a little like slidingDrawer on Android).
I explain myself, i've implemented a xaml interface which look like this :
http://img15.hostingpics.net/pics/974529onglet.png
The code of this interface :
<StackPanel VerticalAlignment="top" Orientation="Horizontal" Height="402" Width="480">
<StackPanel Width="161" Margin="0,10,0,0" >
<StackPanel Height="50" Background="DarkCyan">
<TextBlock Height="50" Text="Qualité orale" Foreground="White" />
</StackPanel>
<StackPanel Height="50" >
<TextBlock Text="Compréhension" Foreground="White" />
</StackPanel>
<StackPanel Height="50">
<TextBlock Text="Général" Foreground="White"/>
</StackPanel>
<StackPanel Height="50">
<TextBlock Text="Fichiers relatifs" Foreground="White"/>
</StackPanel>
<StackPanel Height="50">
<TextBlock Text="Le conférencier" Foreground="White"/>
</StackPanel>
<StackPanel Height="50">
<TextBlock Text="Questions" Foreground="White"/>
</StackPanel>
</StackPanel>
What i want to do here is that when the user touch a stackpanel, the stackpanel change his colour and the gray content at the right change too.
Can you help me solve my problem ?
Thank you in advance
Simply add Tap attributes to the TextBlocks and handle the events from the code behind.
For example:
<TextBlock Text="Questions"
Foreground="White"
Tap="MyEventHandler"
/>
Then you would want to give Name attributes to your StackPanels so that you can reference it in your code. Like so:
<StackPanel Height="50" Name="QuestionsStackPanel">
<TextBlock Text="Questions" Foreground="White"/>
</StackPanel>
In the code behind file, visual studio may auto generate the method stub, if not it should look like this.
private void MyEventHandler(object sender, System.Windows.Input.GestureEventArgs e)
{
//Make changes here
QuestionsStackPanel.Background = Colors.Blue
}
From here you can change the colors of the specific tabs and the grey area you mentioned.
First, Just for informations, the "android tabs interface" is not in agreement with the "UI (metro)" interface. It's not very very important, for more information about a "Ui design style you can go here for styling your app :d
For your Problem, in your Xaml, you can add an event for detect the click (or other event in your 'TextBlock'.
For sample, you can add a "Tap Event" in all your button in your "Code.xaml" (also, You can add a "Name" attribute for find easily your control after):
<StackPanel VerticalAlignment="top" Orientation="Horizontal" Height="402" Width="480">
<StackPanel Name ="Global_Onglets" Width="161" Margin="0,10,0,0" >
<StackPanel Height="50" Background="DarkCyan">
<TextBlock Height="50"
Text="Qualité orale"
Name="TextBlock_Quality"
Tap="MyPersonalEvent"
Foreground="White" />
</StackPanel>
<StackPanel Height="50" >
<TextBlock Text="Compréhension"
Name="TextBlock_Comprehension"
Tap="MyPersonalEvent"
Foreground="White" />
</StackPanel>
<StackPanel Height="50">
<TextBlock Text="Général"
Name="TextBlock_General"
Tap="MyPersonalEvent"
Foreground="White"/>
</StackPanel>
</StackPanel>
</StackPanel>
And, in your "code.cs", you create your event method :
/// <summary>
/// Event handler called by Textblock Tap.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MyPersonalEvent(object sender, EventArgs e)
{
// Get, the current textblock where called the event.
TextBlock CurrentTextBlock = sender as TextBlock;
// Check just the clicked textBlock, for attributes specific colors..
foreach (TextBlock textblock in Global_Onglets.Children)
{
if (textblock == sender)
{
// Attribute secific color for this tap textblock;
}
// Attribute a "normal" color for alls others textBlock..
}
}
You can have more details about events here!!
Also, I saw You create your app in French. But, You can easy Localized your application for create here in other languages (and distrube in other country...) if you want you've a great tutorial here about "localizing your app"... Better think before, that any duty again later. :D

Reference a childitem of a grid defined by a datatemplate in windows 8

I am having a hard time doing the following:
I have a datatemplate which populates a gridview with grids. The number of grids to be generated depends on the data binding, that is how many of the data objects it returns. My grid, which is defined in the datatemplate, contains some controls; namely an image and a textbox.
I am trying to reference the image on the event selectionchanged of the gridview but I am failing majestically. Here is a sample code of what I am trying to do:
The datatemplate (in style.xaml):
<DataTemplate x:Key="tmplMenu">
<Grid Width="100"
Height="100"
Margin="0,0,10,10">
<Border Background="{Binding bgColor}" />
<Image Source="{Binding imgPath}"
Stretch="None"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<TextBlock Text="{Binding description}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
The gridview (in mainpage.xaml for example):
<GridView ItemTemplate="{StaticResource tmplMenu}"
x:Name="myGrid"
Margin="50,20,0,50"
Width="360"
SelectionChanged="myGrid_SelectionChanged">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid Orientation="Horizontal"></WrapGrid>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
Now the selectionChanged event on the gridview (where I would like to reference the image in the datatemplate):
private void myGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
/**REFERENCE IMAGE (which is a child item of the generated grid) OF CLICKED GRID (which is a child item of the gridview) HERE **/
}
Here, the selectionChangedEventArgs e returns the data object which is used to generate the grid instead of the grid itself.
Can anyone help me out in referencing the image control of the clicked item?