Accessing Silverlight Control template items codebehind - c#

I have a control template in page Layout as following.
<Grid x:Name="LayoutRoot">
<Grid.Resources>
<ControlTemplate x:Key="myTemplate" TargetType="esri:MapTip">
<Border CornerRadius="10" Background="#DDFFEEEE" BorderThickness="4" BorderBrush="#99FF0000">
<StackPanel Background="#DDFFFFFF">
<sdk:TabControl Height="180" Margin="5" Name="tabControl1" Width="300">
<sdk:TabItem Header="Info" Name="infoTab">
<TextBlock x:Name="cityInfoTxt" Tag="{Binding [City_ID]}"/>
</sdk:TabItem>
</sdk:TabControl>
</StackPanel>
</Border>
</ControlTemplate>
In code behind how can I access the ??
I tried this,
private void button1_Click(object sender, RoutedEventArgs e)
{
var te = this.LayoutRoot.Resources["myTemplate"] as ControlTemplate;
}
but can not access the textblock in the tab control.

override the method OnAplyTemplate() on code behind and try to find your component.
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var myTextBlock = GetTemplateChild("cityInfoTxt") as TextBlock;
}
Hope it helps

Related

Changing Text value of TextBlock embedded within a Control Template

I have a TextBlock that is inside a Control Template. I want to change the Text for said TextBlock with the Text value of a TextBox. The value is meant to be set within a button click event however, with the way I've tried to do this it doesn't work. The click event will give out an error stating that text is null.
I am new to WPF and would appreciate any help.
XAML for Control Template:
<Window.Resources>
<ControlTemplate x:Key="panel" TargetType="Button">
<Grid>
<Rectangle x:Name="rectangle" Width="auto" Height="55" RadiusX="10" RadiusY="10"
Fill="White">
</Rectangle>
<TextBlock x:Name="txtBlk" Text="" Margin="10,10,0,0" />
</Grid>
</ControlTemplate>
</Window.Resources>
C# for Button_Click event:
private void panelBtn_Click(object sender, RoutedEventArgs e)
{
var text = (TextBlock)this.Template.FindName("txtBlk", this);
text.Text = txtBox.Text;
}
You should reference the template of the button like this..
private void panelBtn_Click(object sender, RoutedEventArgs e)
{
if (sender is Button btn)
{
var text = btn.Template.FindName("txtBlk", btn) as TextBlock;
text.Text = txtBox.Text;
}
}
#MuhammadSulaiman answered you correctly, but I would suggest that you change the implementation.
Rather than looking for an element in a template, it's better to add a resource to which this element will refer and change this resource.
<Window.Resources>
<sys:String x:Key="button.Text">Some Text</sys:String>
<ControlTemplate x:Key="panel" TargetType="Button">
<Grid>
<Rectangle x:Name="rectangle" Width="auto" Height="55" RadiusX="10" RadiusY="10"
Fill="White">
</Rectangle>
<TextBlock x:Name="txtBlk"
Text="{DynamicResource button.Text}"
Margin="10,10,0,0" />
</Grid>
</ControlTemplate>
</Window.Resources>
private void panelBtn_Click(object sender, RoutedEventArgs e)
{
if (sender is FrameworkElement elm)
{
elm.Resources["button.Text"] = txtBox.Text;
}
}
You can also change the initial text in XAML:
<Button Template="{DynamicResource panel}">
<Buttun.Resources>
<sys:String x:Key="button.Text">Other Text</sys:String>
</Buttun.Resources>
</Buttun>
In the same way, you can set a common initial text for all buttons located in one common container, through the resources of this container.

Access children from contextmenu control template c#

I am trying to access a control from a control's context menu's control template.My xaml is :
<Button x:Name="button1" ContextMenuService.Placement="top" Content="Button" HorizontalAlignment="Left" Margin="2,543,0,0" VerticalAlignment="Top" Width="75" Grid.ColumnSpan="2">
<Button.ContextMenu>
<ContextMenu x:Name="btconmn" >
<ContextMenu.Template>
<ControlTemplate>
<Grid x:Name="newgrid" Width="183" Height="190">
<Rectangle Fill="#FF263349" x:Name="newfolder" HorizontalAlignment="Left" VerticalAlignment="Top" Width="179" Height="32" Margin="2,1,0,0"/>
</Grid>
</ControlTemplate>
</ContextMenu.Template>
</ContextMenu>
</Button.ContextMenu>
</Button>
Here i'm trying to access the newfolder rectangle. So far i tried :
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var template = btconmn.Template;
var myControl = (Rectangle)template.FindName("newfolder", btconmn);
}
which returns a null reference exception.Any help ?
WPF controls usually don't load until they are needed, so in your case the earliest point at which you can access the rectangle would be after the button's contextmenu is loaded (which happens immediately before it opens for the first time):
Add this to your XAML:
<ContextMenu x:Name="btconmn" Loaded="Btconmn_OnLoaded">
And this in your code behind:
private void Btconmn_OnLoaded(object sender, RoutedEventArgs e)
{
var template = btconmn.Template;
var myControl = (Rectangle)template.FindName("newfolder", btconmn);
}

Get button content in event

I have the code in XAML:
<Button Grid.Column="0" Grid.Row="1" x:Name="btnSete" Click="btn_Click">
<ContentControl.Content>
<Viewbox Margin="3">
<TextBlock Text="7"/>
</Viewbox>
</ContentControl.Content>
</Button>
And code behind:
private void btn_Click(object sender, RoutedEventArgs e)
{
Button btn = (Button)e.Source;
txbDisplay.Text = btn.Content.ToString();
}
how do I get the value of <TextBlock Text="7"/> in btn_Click?
Based on your XAML, btn.Content should be the instance of the Viewbox. Then the Child property of the Viewbox should be your TextBlock.
So you should be able to do this (inside your button click event handler):
var viewBox = (Viewbox)btn.Content;
var textBlock = (TextBlock)viewBox.Child;
var text = textBlock.Text; // This is the value you were looking for
txbDisplay.Text = text;
Also, just as a helpful note, the <ContentControl.Content> ... </ContentControl.Content> part of your XAML is superfluous. That block could just be written as:
<Button Grid.Column="0" Grid.Row="1" x:Name="btnSete" Click="btn_Click">
<Viewbox Margin="3">
<TextBlock Text="7"/>
</Viewbox>
</Button>
See the "XAML Content Properties" section on this page for more information why that is if you're not sure.

How to Highlight a Selected Item in LongListSelector

I would like to simply show a border around the currently selected item in my LongListSelector. I have set an ItemTemplate for my LongListSelector, but I am unsure of how to modify the Border so that only the currently selected item contains a border.
MainPage.xaml
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="ItemTemplate">
<!-- BorderBrush of all items are currently set to PhoneAccentBrush, need only currently selected item! -->
<Border x:Name="brd" CornerRadius="10" BorderBrush="{StaticResource PhoneAccentBrush}" Width="Auto" BorderThickness="3">
<Viewbox Width="108" Height="108">
<Image x:Name="recentImage" Source="{Binding Source}" Margin="6,6" Width="108"/>
</Viewbox>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu x:Name="imgListContextMenu" Background="{StaticResource PhoneChromeBrush}">
<toolkit:MenuItem Foreground="{StaticResource PhoneForegroundBrush}" Header="delete" Click="deleteContextMenuItem_Click"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</Border>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
...
<phone:LongListSelector x:Name="Recent" Margin="0"
SelectionChanged="recent_SelectionChanged"
toolkit:TiltEffect.IsTiltEnabled="True"
LayoutMode="Grid" GridCellSize="108,108"
ItemTemplate="{StaticResource ItemTemplate}"
/>
Currently all of the items within the LongListSelector show the border. I would prefer to modify this in the code behind, but what I have thus far does not work
MainPage.xaml.cs
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = sender as LongListSelector
item.BorderBrush = App.Current.Resources["PhoneAccentBrush"] as SolidColorBrush;
}
Any ideas?
When you access the selected item, you should access it as a border and not as a LongListSelector because that's how you show each item, while the LongListSelector is the container. You also forgot a semi-colon on the 3rd row, I've added it for you.
Your new code would be:
private void recent_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var item = sender as Border;
item.BorderBrush = App.Current
.Resources["PhoneAccentBrush"] as SolidColorBrush;
}

make data grid visible on click

I have this data grid where I am placing all my buttons
<Grid x:Name="ButtonGrid" HorizontalAlignment="Left" Margin="0,90,0,4" Width="186">
<Button x:Name="B1" Content="B1" Height="18" Margin="73,0,59,16" VerticalAlignment="Bottom" Click="B1"/>
<Button x:Name="B2" Content="B2" Height="18" Margin="0,0,-2,16" VerticalAlignment="Bottom" Click="B2_Click" HorizontalAlignment="Right" Width="57"/>
</Grid>
I have the grid collapased on start. But when a button {testGrid} is clicked, I want the grid to ne visible.
Here is my code
namespace project.Test
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
EDUTED
private void testGrid_Click(object sender, System.Windows.RoutedEventArgs e)
{
FrameworkElement ButtonGrid = (sender as FrameworkElement).FindName("ButtonGrid") as FrameworkElement;
if ( ButtonGrid.Visibility == System.Windows.Visibility.Collapsed)
ButtonGrid.Visibility = System.Windows.Visibility.Visible;
else
ButtonGrid.Visibility = System.Windows.Visibility.Collapsed;
}
}
}
I think if you move your Grid outside of your DataTemplate it will work. :)
However if you really need to put it in a DataTemplate, as long as your Button is at the same level as the Grid, you should still be able to find it.
Say your xaml code looks like this,
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="controlstoryboardactionrefissue.MainPage" Width="640" Height="480">
<UserControl.Resources>
<DataTemplate x:Key="DataTemplate1">
<Grid x:Name="myGrid" Height="128" Background="#FFE7C0C0" Width="333">
<Button x:Name="myButton" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="31,29,0,0" Click="myButton_Click" />
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<ContentControl HorizontalAlignment="Left" VerticalAlignment="Top" Margin="175,198,0,0" ContentTemplate="{StaticResource DataTemplate1}" />
</Grid>
</UserControl>
Then the code behind,
private void myButton_Click(object sender, System.Windows.RoutedEventArgs e)
{
var myButton = (Button)sender;
var grid = myButton.Parent as Grid;
if (grid != null)
{
// do stuff
}
}
Hope it helps. :)

Categories

Resources