I have the following code:
<ScrollViewer x:Name="swipeBetweenPages" Grid.Row="1">
<Pivot DataContext="{StaticResource ViewModel}" x:Name="pivot" Margin="0,-45,0,0"
HeaderTemplate="{StaticResource headerTest}"
ItemTemplate="{StaticResource pivotTemplate}" ItemsSource="{Binding Articles}" SelectionChanged="pivot_SelectionChanged">
</Pivot>
</ScrollViewer>
<Page.Resources>
<ViewModels:ArticleViewModel x:Key="ViewModel" />
<DataTemplate x:Key="headerTest">
</DataTemplate>
<DataTemplate x:Key="pivotTemplate">
<StackPanel Margin="-15 0 -15 0">
<Grid>
<Grid.Background>
<ImageBrush AlignmentX="Center" AlignmentY="Center" ImageSource="Assets/PlaceHolder.jpg"></ImageBrush>
</Grid.Background>
<Image q42controls:ImageExtensions.CacheUri="{Binding ImageURL}" Tag="{Binding ImageURL}" Tapped="ImageView"></Image>
</Grid>
<StackPanel Background="White">
<TextBlock x:Name="HeadLine" Text="{Binding HeadLine}"
Margin="10 5 0 -5" TextWrapping="Wrap"
FontSize="20" Foreground="Black"
FontFamily="{StaticResource HeadlineCommonFamiy}"
Pivot.SlideInAnimationGroup="GroupTwo" Height="63"
FontWeight="Bold" TextTrimming="CharacterEllipsis"/>
<TextBlock Text="{Binding Abstract}" TextWrapping="Wrap" FontSize="15" FontStyle="Italic"
Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
FontFamily="{StaticResource AbstractCommonFamily}"/>
</StackPanel>
<StackPanel x:Name="descriptionSP" Background="White">
<RichTextBlock IsTextSelectionEnabled="False" x:Name="richTextBlock"
local:Properties.Html="{Binding ArticleDetail}" TextWrapping="Wrap"
Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
FontFamily="{StaticResource ContentControlThemeFontFamily}">
</RichTextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</Page.Resources>
I am trying to set the font size to rich text block in the back end dynamically.
Now, I am trying with the following code in the C# end:
private T FindElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0) return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
return (T)child;
else
{
var result = FindElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
RichTextBlock richTextBlock = new RichTextBlock();
StackPanel rootStackPanel = new StackPanel();
StackPanel childStackPanel = new StackPanel();
PivotItem item = (sender as Pivot).ContainerFromItem((sender as Pivot).SelectedItem) as PivotItem;
rootStackPanel = item.ContentTemplate.LoadContent() as StackPanel;
childStackPanel = rootStackPanel.FindName("descriptionSP") as StackPanel;
richTextBlock = rootStackPanel.FindName("richTextBlock") as RichTextBlock;
Paragraph paragraph = new Paragraph();
Run run = new Run();
// Customize some properties on the RichTextBlock.
richTextBlock.IsTextSelectionEnabled = true;
richTextBlock.SelectionHighlightColor = new SolidColorBrush(Windows.UI.Colors.Pink);
richTextBlock.Foreground = new SolidColorBrush(Windows.UI.Colors.Blue);
richTextBlock.FontWeight = Windows.UI.Text.FontWeights.Light;
richTextBlock.FontFamily = new FontFamily("Arial");
richTextBlock.FontStyle = Windows.UI.Text.FontStyle.Italic;
richTextBlock.FontSize = 50;
//run.Text = "This is some sample text to demonstrate some properties.";
paragraph.Inlines.Add(run);
richTextBlock.Blocks.Add(paragraph);
// Add the RichTextBlock to the visual tree (assumes stackPanel is decalred in XAML).
//childStackPanel.Children.Add(richTextBlock);
//rootStackPanel.Children.Add(richTextBlock);
But, it is not affecting the font size.
Please help me.
Thanks.
You can create a Property in your ViewModel or code behind file and use data binding to connect it to the FontSize property.
private double _myFontSize;
public double MyFontSize
{
get{ return _myFontSize; }
set{ _myFontSize = value; }
}
Now inside your data template for the font size of the rich text box,
FontSize="{Binding MyFontSize, ElementName=page/viewModel}"
And remember to use 'INotifyPropertyChanged' to notify the UI when the value of your property changes. This web site provides a guide on implementing 'INotifyPropertyChanged'
Related
I have task to create in C# UWP user created check-list.
But I have stuck from the beginning cause XAML is new for me, so I have no idea what to start from.
So, I have textbox to enter title, task or subtask to in listbox (priviously added to) selected task.
this is my xaml how it looks like now:
<Page
x:Class="Table1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Table1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<TextBox x:Name="txt" HorizontalAlignment="Left" Height="71" Margin="71,247,0,0" Text="TextBox" VerticalAlignment="Top" Width="395"/>
<RadioButton x:Name="title" Content="Add Title" HorizontalAlignment="Left" Margin="71,86,0,0" VerticalAlignment="Top"/>
<RadioButton x:Name="task" Content="Add Task" HorizontalAlignment="Left" Margin="71,123,0,0" VerticalAlignment="Top"/>
<RadioButton x:Name="subtask" Content="Add Subtask" HorizontalAlignment="Left" Margin="71,155,0,0" VerticalAlignment="Top"/>
<ListBox x:Name="listbox" HorizontalAlignment="Left" Height="68" Margin="71,354,0,0" VerticalAlignment="Top" Width="395"/>
<Button x:Name="btn" Content="Button" HorizontalAlignment="Left" Margin="401,483,0,0" VerticalAlignment="Top" Click="btn_Click"/>
</Grid>
</Page>
There are the code:
public class subtasks
{
public string parent { get; set; }
public string subtask { get; set; }
public subtasks(string parenti, string subtaski)
{
parent = parenti;
subtask = subtaski;
}
public void setsub(string parenti, string sub)
{
parent = parenti;
subtask = sub;
}
}
List<string> Tasks = new List<string>();
List<subtasks> sub = new List<subtasks>();
private void btn_Click(object sender, RoutedEventArgs e)
{
string parent = "";
string Title;
string Task;
string Subtask;
if (title.IsChecked==true)
{
Title = txt.Text;
adding(Title, parent, 1);
}
else if (task.IsChecked==true)
{
Task = txt.Text;
adding(Task, parent, 2);
}
else if (subtask.IsChecked==true)
{
parent = listbox.SelectedItem.ToString();
Subtask = txt.Text;
adding(Subtask, parent, 3);
}
else
{
}
}
private void adding(string str, string par, int x)
{
subtasks subi = new subtasks(par,str);
RowDefinition row = new RowDefinition();
TextBlock text = new TextBlock();
if (x==1)
{
print(str);
}
else if (x==2)
{
Tasks.Add(str);
listbox.Items.Add(str);
text.Text = str;
print(str);
}
else
{
sub.Add(subi);
print(str);
}
}
private void print(string title)
{
int step = 0;
Grid gridwin = new Grid();
gridwin.Children.Clear();
RowDefinition row = new RowDefinition();
TextBlock text = new TextBlock();
text.Text = title;
Grid.SetColumn(text, 0);
Grid.SetRow(text, step);
step++;
for (int i = 0; i < Tasks.Count; i++)
{
text.Text = Tasks[i].ToString();
gridwin.Children.Add(text);
Grid.SetColumn(text, 0);
Grid.SetRow(text, step);
step++;
for (int k = 0; k < sub.Count; k++)
{
if (sub[k].parent == Tasks[i])
{
text.Text = sub[k].subtask.ToString();
gridwin.Children.Add(text);
Grid.SetColumn(text, 0);
Grid.SetRow(text, step);
step++;
}
}
}
}
As you see I need to clear and put data every time the button is clicked, cause you never know when user will decide to add new subtask for previously added task. So, the question is, how to make the table with column1 with tasks and subtasks and column2 which is chekbox.
What you want to probably do is to create a DataTemplate. You use this to specify how list items should be displayed and formatted. This way you can specify you want to lay them out as a Grid with two columns like description and CheckBox. Take a look into the documentation to see some examples of DataTemplates. You can also see the Azure Mobile Apps quickstart for UWP, because although it is focused on demonstrating Microsoft Azure integration to UWP, it is actually a to-do app, which should give you some inspiration for building your own.
The layout could look like this:
<ListBox x:Name="listbox" HorizontalAlignment="Left" Height="68" Margin="71,354,0,0" VerticalAlignment="Top" Width="395">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Text}" />
<CheckBox Grid.Column="1" IsChecked="{Binding IsChecked, Mode=TwoWay}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can see my code is also using {Binding} syntax, which you will also need to learn a bit about to be able to know when the user has checked a to-do item in the list. I suggest you to take a look at a simple tutorial sample like here. In fact, data-binding is one of the most important things when building XAML-based apps and when you get to understand this concept, it will help you a lot on the way to becoming a UWP ninja :-) .
Why dont use the UWP DataGrid with CheckBox?
XAML
<toolkit:DataGrid Grid.Column="0" ItemsSource="{x:Bind myItemsToBind}"
x:Name="dgwDeviceSPNs" MinWidth="100"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalScrollBarVisibility="Visible"
VerticalScrollBarVisibility="Visible"
AlternatingRowBackground="Transparent"
AreRowDetailsFrozen="False"
AreRowGroupHeadersFrozen="True"
AutoGenerateColumns="False"
CanUserSortColumns="False"
CanUserReorderColumns="True"
RowGroupHeaderPropertyNameAlternative=""
CanUserResizeColumns="True"
MaxColumnWidth="200"
FrozenColumnCount="0"
GridLinesVisibility="Horizontal"
HeadersVisibility="None"
IsReadOnly="True"
RowDetailsVisibilityMode="Collapsed"
SelectionMode="Single">
<toolkit:DataGrid.Columns>
<toolkit:DataGridTemplateColumn MinWidth="10">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Padding="2">
<CheckBox ToolTipService.ToolTip="{Binding Name}" IsChecked="{Binding IsSelected, Mode=TwoWay}" Content="{Binding Name}"></CheckBox>
</StackPanel>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
</toolkit:DataGrid.Columns>
</toolkit:DataGrid>
I have the following code:
<ScrollViewer x:Name="swipeBetweenPages" Grid.Row="1">
<Pivot DataContext="{StaticResource ViewModel}" x:Name="pivot" Margin="0,-45,0,0"
HeaderTemplate="{StaticResource headerTest}"
ItemTemplate="{StaticResource pivotTemplate}" ItemsSource="{Binding Articles}" SelectionChanged="pivot_SelectionChanged">
</Pivot>
</ScrollViewer>
<Page.Resources>
<ViewModels:ArticleViewModel x:Key="ViewModel" />
<DataTemplate x:Key="headerTest">
</DataTemplate>
<DataTemplate x:Key="pivotTemplate">
<StackPanel Margin="-15 0 -15 0">
<Grid>
<Grid.Background>
<ImageBrush AlignmentX="Center" AlignmentY="Center" ImageSource="Assets/PlaceHolder.jpg"></ImageBrush>
</Grid.Background>
<Image q42controls:ImageExtensions.CacheUri="{Binding ImageURL}" Tag="{Binding ImageURL}" Tapped="ImageView"></Image>
</Grid>
<StackPanel Background="White">
<TextBlock x:Name="HeadLine" Text="{Binding HeadLine}"
Margin="10 5 0 -5" TextWrapping="Wrap"
FontSize="20" Foreground="Black"
FontFamily="{StaticResource HeadlineCommonFamiy}"
Pivot.SlideInAnimationGroup="GroupTwo" Height="63"
FontWeight="Bold" TextTrimming="CharacterEllipsis"/>
<TextBlock Text="{Binding Abstract}" TextWrapping="Wrap" FontSize="15" FontStyle="Italic"
Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
FontFamily="{StaticResource AbstractCommonFamily}"/>
</StackPanel>
<StackPanel x:Name="descriptionSP" Background="White">
<RichTextBlock IsTextSelectionEnabled="False" x:Name="richTextBlock"
local:Properties.Html="{Binding ArticleDetail}" TextWrapping="Wrap"
Pivot.SlideInAnimationGroup="GroupTwo" Margin="10 5 0 10"
FontFamily="{StaticResource ContentControlThemeFontFamily}">
</RichTextBlock>
</StackPanel>
</StackPanel>
</DataTemplate>
</Page.Resources>
How to get the RichTextBlock control inside the stackpanel?
Now, I am trying with the following code in the C# end:
private T FindElementInVisualTree<T>(DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0) return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
return (T)child;
else
{
var result = FindElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
RichTextBlock richTextBlock = new RichTextBlock();
StackPanel rootStackPanel = new StackPanel();
StackPanel childStackPanel = new StackPanel();
PivotItem item = (sender as Pivot).ContainerFromItem((sender as Pivot).SelectedItem) as PivotItem;
rootStackPanel = item.ContentTemplate.LoadContent() as StackPanel;
childStackPanel = rootStackPanel.FindName("descriptionSP") as StackPanel;
richTextBlock = rootStackPanel.FindName("richTextBlock") as RichTextBlock;
Paragraph paragraph = new Paragraph();
Run run = new Run();
// Customize some properties on the RichTextBlock.
richTextBlock.IsTextSelectionEnabled = true;
richTextBlock.SelectionHighlightColor = new SolidColorBrush(Windows.UI.Colors.Pink);
richTextBlock.Foreground = new SolidColorBrush(Windows.UI.Colors.Blue);
richTextBlock.FontWeight = Windows.UI.Text.FontWeights.Light;
richTextBlock.FontFamily = new FontFamily("Arial");
richTextBlock.FontStyle = Windows.UI.Text.FontStyle.Italic;
richTextBlock.FontSize = 50;
//run.Text = "This is some sample text to demonstrate some properties.";
//Add the Run to the Paragraph, the Paragraph to the RichTextBlock.
paragraph.Inlines.Add(run);
richTextBlock.Blocks.Add(paragraph);
// Add the RichTextBlock to the visual tree (assumes stackPanel is decalred in XAML).
//childStackPanel.Children.Add(richTextBlock);
//rootStackPanel.Children.Add(richTextBlock);
But I am not able to get the control RichTextBlock. I am getting a null value.
Please help me.
Thanks.
You can use ContentTemplate of PivotItem to get the template of PivotItem for example like this:
PivotItem item = (sender as Pivot).ContainerFromItem((sender as Pivot).SelectedItem) as PivotItem;
var rootStackPanel = item.ContentTemplate.LoadContent() as StackPanel;
var richtb = rootStackPanel.FindName("richtb") as RichTextBlock;
And I firstly gave a name to the RichTextBlock as "richtb".
The code you provided searches the tree for the first matching control of the given type. This means, that what you get in return is the first StackPanel in the XAML definition, but the RichTextBlock in the second one.
Why don't you directly do this, instead of searching for the StackPanel:
var richTextBlock = FindElementInVisualTree<RichTextBlock>(item);
This will return the RichTextBlock directly, because the FindElementInVisualTree method is searching down the tree recursively.
Please have a look at this image to understand my scenario
So I have the above scenario in my Windows Phone application where I have a ListBox with the below layout.
My XAML for the ListBox
<ListBox x:Name="llsIceCreamBrands" Margin="0,54,0,0" CacheMode="BitmapCache">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="0,0,0,40">
<StackPanel>
<Border BorderBrush="{StaticResource PhoneProgressBarBackgroundBrush}" BorderThickness="3">
<Image Width="200" Height="200" Source="{Binding IceCreamBrandImage }" Margin="3,0,0,0" Stretch="Fill"/>
</Border>
</StackPanel>
<StackPanel>
<Grid Margin="20,-5,0,0" Height="250" >
<StackPanel>
<TextBlock Text="{Binding IceCreamBrandName }" FontWeight="SemiBold" FontSize="34" FontFamily="Segoe WP" Margin="0" TextWrapping="Wrap" Width="184" VerticalAlignment="Top" HorizontalAlignment="Left" Opacity="1" LineStackingStrategy="BlockLineHeight" LineHeight="35" Height="Auto" />
<TextBlock Text="{Binding IceCreamBrandFlavour }" FontWeight="Normal" FontSize="15" FontFamily="Segoe WP" TextWrapping="Wrap" VerticalAlignment="Top" Width="200" Opacity="0.7" HorizontalAlignment="Left" IsHitTestVisible="False" Height="140"/>
</StackPanel>
</Grid>
</StackPanel>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In C# Code:
void GetIceCreamBrands()
{
string mystring = "";
for (int i = 0; i < dc.IceCreams[cID].Brands.Count; i++)
{
var bmp = new BitmapImage();
if (dc.IceCreams[cID].Brands[i].HasArt)
{
bmp.SetSource(dc.IceCreams[cID].Brands[i].GetImage());
}
else
{
bmp.CreateOptions = BitmapCreateOptions.None;
bmp.UriSource = new Uri("/Assets/Images/IceCreams/Placeholder.png", UriKind.Relative);
}
for (int j = 0; j < dc.IceCreams[cID].Brands.Count; j++)
{
for (int k = 0; k < dc.IceCreams[cID].Brands[j].Flavour.Count; k++)
{
sourceFlavourList.Add(new Flavour
{
FlavourBrand = dc.IceCreams[cID].Brands[j].Name,
BrandFlavourName = dc.IceCreams[cID].Brands[j].Flavour[k].Name
});
}
}
sourceIceCreamBrands.Add(new IceCreamBrands
{
IceCreamBrandName = dc.IceCreams[cID].Brands[i].Name,
IceCreamBrandImage = bmp,
IceCreamBrandFlavour = "Get Flavours here for the particular brand somehow?"
});
}
llsIceCreamBrands.ItemsSource = sourceIceCreamBrands.ToList();
}
I have the above method in my code which successfully gets the brands and their images, but the flavours are also a Collection which I tried to get in a single string by using
string mystring = string.Join(Environment.NewLine, sourceFlavourList.Select(x => x.IceCreamBrandFlavourName));
But this returns the same values for both Ben&Jerrys and Haagen-Dazs - which is an amalgamation of both brands' flavours.
How can I achieve what I'm looking for?
I don't see where you define the variable 'sourceFlavourList' within GetIceCreamBrands(), so I assume you have this defined elsewhere in your code. This would explain why you see the full list of flavours (from both brands) as you keep adding all flavours to this one variable.
So instead of using this full list variable, you would need to bind to a per brand list (which you DO have in your result)., so you can use the same linq you have, but with a different source variable).
Try something like this:
var flavours = string.Join(Environment.NewLine, dc.IceCreams[cID].Brands[j].Flavour.Select(x => x.Name));
sourceIceCreamBrands.Add(new IceCreamBrands
{
IceCreamBrandName = dc.IceCreams[cID].Brands[i].Name,
IceCreamBrandImage = bmp,
IceCreamBrandFlavour = flavours
});
I want to binding my itemscontrol in listbox, but it doesn't work. I want to add some FrameworkElement to Listbox with stack style.
Here is my XAML code:
<ListBox x:Name="listThemes">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" FontWeight="Bold" />
<StackPanel Grid.Row="1" >
<ItemsControl Width="Auto"
Height="Auto"
ItemsSource="{Binding ElementName=listThemes, Path=Items}">
</ItemsControl>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I don't know how to binding ItemsControl inside ListBox. I try put out the Binding ElementName of ItemsControl but it's always crashes. If the ElementName is page name, it not work.
Testing Class :
public class Testing
{
public string Title { get; set; }
public ObservableCollection<FrameworkElement> Items { get; set; }
}
C# Code :
observableCollection = new ObservableCollection<FrameworkElement>();
for (int i = 0; i < 3; i++)
{
observableCollection.Add(new Button { Content = i.ToString() });
observableCollection.Add(new Canvas
{
Background = new ImageBrush()
{
ImageSource = new BitmapImage(new Uri(#"Assets/ApplicationIcon.png", UriKind.Relative)),
Stretch = System.Windows.Media.Stretch.Fill
},
Height = 100,
Width = 100
});
}
List<Testing> list = new List<Testing>();
for (int i = 0; i < 3; i++)
{
Testing test = new Testing();
test.Title = "Testing";
test.Items = observableCollection;
list.Add(test);
}
listThemes.ItemsSource = list;
First, it crashes because you bind the same elements on three different item. One framework element can't be attach under two different control. So you should place your ObservableCollection in your List<Testing> creating process.
Second, you should set a DataContext to your listThemes control, so its items can find the right data path to bind and then you could remove the ElementName.
Try these code.
List<Testing> list = new List<Testing>();
for (int i = 0; i < 3; i++)
{
Testing test = new Testing();
test.Title = "Testing";
var observableCollection = new ObservableCollection<FrameworkElement>();
for (int j = 0; i < 3; i++)
{
observableCollection.Add(new Button { Content = j.ToString() });
observableCollection.Add(new Canvas
{
Background = new ImageBrush()
{
ImageSource = new BitmapImage(new Uri(#"Assets/ApplicationIcon.png", UriKind.Relative)),
Stretch = System.Windows.Media.Stretch.Fill
},
Height = 100,
Width = 100
});
}
test.Items = observableCollection;
list.Add(test);
}
listThemes.DataContext = list;
listThemes.ItemsSource = list;
Third, I don't think it is a good way to bind your FrameworkElement directly to an ItemsControl. It just look weird.
Update:
If you want to generate different types of items, you can use DataTemplateSelector. Because you already parse the forum data into different type, so please check this post:
How to Control the DataTemplateSelector in Windows Store Apps
It explains how to use DataTemplateSelector to display different type of data.
Why is your inner collection of type FrameworkElement?
Create a custom type for it and set an ItemTemplate for your inner ItemsControl.
<DataTemplate x:Key=NestedItemsTemplate>
....
</DataTemplate>
<ListBox x:Name="listThemes"
ItemsSource="{Binding TestItems}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" FontWeight="Bold" />
<StackPanel Grid.Row="1" >
<ItemsControl
Width="Auto" Height="Auto"
ItemsSource="{Binding ElementName=listThemes, Path=Items}"
ItemTemplate="{StaticResource NestedItemsTemplate}">
</ItemsControl>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
In my WP8 appliciation's App.xaml file I've defined ControlTemplate as following:
<Application.Resources>
<ControlTemplate x:Name="AddReminderDialog">
<Canvas HorizontalAlignment="Center" Height="320" Width="260"
VerticalAlignment="Center" Background="White" Margin="110,178,110,238">
<TextBlock Foreground="Black" Text="Напомнить" FontSize="15" HorizontalAlignment="Center" Canvas.Left="92" Canvas.Top="38" />
<Button Name="btn1HourBef" BorderThickness="0" Click="NotificationButtonClick" Background="Black" Content="За час" Width="260" FontSize="15" Height="60" Margin="0,70,0,0"/>
<Button Name="btn30MinBef" BorderThickness="0" Click="NotificationButtonClick" Background="Black" Content="За 30 минут" Width="260" FontSize="15" Height="60" Margin="0,130,0,0"/>
<Button Name="btnOnArrDept" BorderThickness="0" Click="NotificationButtonClick" Background="Black" Content="По прилету/вылету" Width="260" FontSize="15" Height="60" Margin="0,190,0,0"/>
<Button Name="btnCancel" BorderThickness="0" Click="NotificationButtonClick" Background="Black" Content="Отменить" Width="260" FontSize="15" Height="60" Margin="0, 250, 0, 0" Visibility="Collapsed"/>
</Canvas>
</ControlTemplate>
</Application.Resources>
I use it as a template of popup as following
private void Image_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
var image = sender as Image; //get the sender iamge
var modelItem = image.DataContext; //get image's data context
const double width = 260;
const double height = 280;
//get the flight id from image's tag property(which was binded in flightInfoDataTemplate)
flightID = Convert.ToString(image.Tag);
//define content for popup
var content = new ContentControl()
{
Width = width,
Height = height,
Background = new SolidColorBrush(Colors.Transparent)
};
//set the template of content to the contentTemplate, which was defined in app.xaml
content.Template = (ControlTemplate)Resources["AddReminderDialog"];
//set popup's datacontext to the image's datacontext
content.DataContext = modelItem;
//popup's child property is setting to our content
popup.Child = content;
popup.Height = height;
popup.Width = width;
popup.VerticalOffset = Application.Current.RootVisual.RenderSize.Height / 2 - height / 2;
popup.HorizontalOffset = Application.Current.RootVisual.RenderSize.Width / 2 - width / 2;
popup.IsOpen = true;
}
I use this popup to set notification. When user taps the image in the first time the btnCancel button should be invisible, because there is nothing to cancel. When the image is tapped the second time, btnCancel should become visible to cancel the notification.
I've set button visibility to collapsed by default. But I have not idea how to access that button in the code behind to make it visible.
So my question is how can I change button's visibility settings in the code behind?
You can do something like this,
private void SearchElement(DependencyObject targeted_control)
{
var count = VisualTreeHelper.GetChildrenCount(targeted_control); // targeted_control is the Canvas
if (count > 0)
{
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(targeted_control, i);
if (child is Button ) // specific button control
{
// do your logic
}
}
}
}