WinRT - App bar not appearing when I tap the ellipses - c#

I'm trying to get my app bar to appear when I tap the 3 dots at the bottom of the screen, but when I do so it doesn't happen. Anyone know why & how this problem can be rectified?
MainPage.xaml
<Page
x:Name="pageRoot"
x:Class="HP.MainPage"
DataContext="{Binding DefaultViewModel, RelativeSource={RelativeSource Self}}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Exits_Expert_London_Lite.Lines_and_Stations.WC"
xmlns:common="using:Exits_Expert_London_Lite.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:q42controls="using:Q42.WinRT.Controls"
mc:Ignorable="d">
<Grid Background="Black">
<Grid.ChildrenTransitions>
<TransitionCollection>
<EntranceThemeTransition/>
</TransitionCollection>
</Grid.ChildrenTransitions>
<Grid Name="CustomAppBarRoot" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Loaded="CustomAppBarRoot_OnLoaded"
ManipulationMode="TranslateY"
ManipulationDelta="CustomAppBarRoot_OnManipulationDelta"
ManipulationCompleted="CustomAppBarRoot_OnManipulationCompleted"
Tapped="CustomAppBarRoot_OnTapped">
<Grid.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Grid.RenderTransform>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.5"></SolidColorBrush>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Name="DotsTextBlock" FontSize="28" Text="..." HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0 0 15 0" Tapped="DotsTextBlock_OnTapped" Width="50" Height="50" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="0" X="11"/>
</TextBlock.RenderTransform>
</TextBlock>
<StackPanel Name="ButtonsStackPanel" Grid.Row="1" Orientation="Horizontal">
<AppBarButton Label="tfg" Icon="Add"/>
<AppBarButton Label="tfg" Icon="Add"/>
</StackPanel>
</Grid>
<Hub>
<Hub.Header>
<!-- Back button and page title -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="backButton" Margin="-1,-1,39,0" Command="{Binding NavigationHelper.GoBackCommand, ElementName=pageRoot}"
Style="{StaticResource NavigationBackButtonNormalStyle}"
VerticalAlignment="Top"
AutomationProperties.Name="Back"
AutomationProperties.AutomationId="BackButton"
AutomationProperties.ItemType="Navigation Button"/>
<TextBlock x:Name="pageTitle" Text="Page name" Style="{StaticResource HeaderTextBlockStyle}" Grid.Column="1"
IsHitTestVisible="false" TextWrapping="NoWrap" VerticalAlignment="Top"/>
</Grid>
</Hub.Header>
<HubSection Width="800" Padding="40,50,0,0">
<HubSection.Header>
<StackPanel>
<TextBlock Text="hub section 1" Style="{StaticResource HeaderTextBlockStyle}"/>
</StackPanel>
</HubSection.Header>
<DataTemplate>
<Grid>
<StackPanel>
<TextBlock Style="{StaticResource SubheaderTextBlockStyle}" Margin="0,0,0,5" TextWrapping="Wrap">
<Run Text="Hello World"/>
</TextBlock>
</StackPanel>
</Grid>
</DataTemplate>
</HubSection>
</Hub>
</Grid>
</Page>
MainPage.cs
using HP.Common;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Navigation;
// The Hub Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=321224
namespace HP
{
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.Tapped += Page_OnTapped;
}
private void Page_OnTapped(object sender, TappedRoutedEventArgs tappedRoutedEventArgs)
{
if ( isAppBarShown )
HideCustomAppBar();
}
#region custom app bar
private Storyboard hideCustomAppBarStoryboard;
private Storyboard showCustomAppBarStoryboard;
private Size appBarSize;
private Size appBarButtonsSize;
private bool isAppBarShown = true;
private void CustomAppBarRoot_OnLoaded(object sender, RoutedEventArgs e)
{
appBarSize = new Size(CustomAppBarRoot.ActualWidth, CustomAppBarRoot.ActualHeight);
appBarButtonsSize = new Size(ButtonsStackPanel.ActualWidth, ButtonsStackPanel.ActualHeight);
InitializeStoryboards();
HideCustomAppBar();
}
private void ShowCustomAppBar()
{
isAppBarShown = true;
showCustomAppBarStoryboard.Begin();
}
private void HideCustomAppBar()
{
isAppBarShown = false;
hideCustomAppBarStoryboard.Begin();
}
private void DotsTextBlock_OnTapped(object sender, TappedRoutedEventArgs e)
{
if (isAppBarShown)
HideCustomAppBar();
else
ShowCustomAppBar();
}
private void InitializeStoryboards()
{
hideCustomAppBarStoryboard = new Storyboard();
showCustomAppBarStoryboard = new Storyboard();
var showDoubleAnimation = new DoubleAnimation()
{
EasingFunction = new CircleEase() {EasingMode = EasingMode.EaseInOut},
To = 0,
Duration = new Duration(TimeSpan.FromMilliseconds(200))
};
var hideDoubleAnimation = new DoubleAnimation()
{
EasingFunction = new CubicEase() {EasingMode = EasingMode.EaseInOut},
To = appBarButtonsSize.Height,
Duration = new Duration(TimeSpan.FromMilliseconds(200))
};
hideCustomAppBarStoryboard.Children.Add(hideDoubleAnimation);
showCustomAppBarStoryboard.Children.Add(showDoubleAnimation);
Storyboard.SetTarget(hideCustomAppBarStoryboard, CustomAppBarRoot);
Storyboard.SetTarget(showCustomAppBarStoryboard, CustomAppBarRoot);
Storyboard.SetTargetProperty(showCustomAppBarStoryboard, "(UIElement.RenderTransform).(TranslateTransform.Y)");
Storyboard.SetTargetProperty(hideCustomAppBarStoryboard, "(UIElement.RenderTransform).(TranslateTransform.Y)");
}
#endregion
private void CustomAppBarRoot_OnManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
var translateTransform = (CustomAppBarRoot.RenderTransform as TranslateTransform);
double newY = e.Delta.Translation.Y + translateTransform.Y;
translateTransform.Y = Math.Max(0, Math.Min(newY, appBarButtonsSize.Height));
}
private void CustomAppBarRoot_OnManipulationCompleted(object sender, ManipulationCompletedRoutedEventArgs e)
{
// if small appbar-position changes are made app bar should back to previous position, just like in windows phone
if (Math.Abs(e.Cumulative.Translation.Y) < 20)
isAppBarShown = !isAppBarShown;
if (!isAppBarShown)
ShowCustomAppBar();
else
HideCustomAppBar();
}
private void CustomAppBarRoot_OnTapped(object sender, TappedRoutedEventArgs e)
{
e.Handled = true; // prevents raising Page.Tapped event so appbar won't be closed on AppBar-area tap
}
}
}

Move your CustomAppBarRoot Grid after the Hub control so it renders on top. As is, the Hub control covers the CustomAppBarRoot so clicks on the ellipses go to the Hub not to the DotsTextBlock. If you give the Hub a background colour for testing this is quite obvious (leave the Background off for production):
<Hub Background="Magenta">
You could also raise the CustomAppBarRoot in the Z-order by applying the Canvas.ZIndex property; however, since your CustomAppBarRoot isn't in a Canvas this is an off-label use so I'd prefer placing the CustomAppBarRoot after the Hub in the Xaml:
<Grid Name="CustomAppBarRoot" Canvas.ZIndex="100" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Loaded="CustomAppBarRoot_OnLoaded"
There is a Segoe UI Symbol for the "More" ellipses at Unicode 0xe10c that you might use rather than using a string of periods:
<TextBlock Name="DotsTextBlock" Text="" FontSize="14" FontFamily="Segoe UI Symbol" HorizontalAlignment="Right" VerticalAlignment="Top"
Margin="0 0 15 0" Tapped="DotsTextBlock_OnTapped" Width="50" Height="50" TextAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="0" X="11"/>
</TextBlock.RenderTransform>
</TextBlock>

Related

How to create databinding in code behind using the same object that is initiated in xaml?

I have the following code :
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication3" xmlns:oxy="http://oxyplot.org/wpf"
xmlns:vm="clr-namespace:ViewModel;assembly=ViewModel"
Background="#FFDEDEDE"
WindowStyle="None"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
Title="Compression Test" Height="1080" Width="1920">
<Window.Resources>
<vm:MainViewModel x:Key="vmMain"
sampleCount="100" />
</Window.Resources>
<Grid x:Name="gridUI">
<StackPanel Orientation="Vertical">
<StackPanel Height="100">
<Border Background="#FF8986D3" Height="100" Margin="0,0,0,30" >
<TextBlock Text="COMPRESSION TEST" FontFamily="Sans-serif" FontSize="30" Foreground="#FFF9F9F9" VerticalAlignment="Center" FontWeight="Medium" HorizontalAlignment="Center"/>
</Border>
</StackPanel>
<StackPanel Orientation="Horizontal" Height="auto">
<Border BorderBrush="White" BorderThickness="2" >
<StackPanel Orientation="Vertical" Width="200" Height="1080">
<Label FontSize="24" FontFamily="Sans-serif" FontWeight="Medium" Name="doc" Foreground="White" Background="#FFA39AD8" Width="200" HorizontalContentAlignment="Center" Height="43">Files</Label>
<Border BorderBrush="#FFD4D4D4" BorderThickness="0.5" Grid.Row="3"></Border>
<StackPanel Name="sp_doc" Margin="0,10,0,0" >
<StackPanel Orientation="Horizontal" Name="sp_sample_button" Grid.Row="0" Grid.Column="0">
<Image Source="pack://application:,,,/Resources/413.png" Height="40" Width="40" UseLayoutRounding="True" MouseDown="sampleDropDown" Cursor="Hand" Margin="5,0,0,0" Name="up_arrow"/>
<Image Source="pack://application:,,,/Resources/412.png" Height="40" Width="40" UseLayoutRounding="True" MouseDown="sampleDropDown" Cursor="Hand" Margin="5,0,0,0" Name="down_arrow" Visibility="Collapsed"/>
<!--<Button x:Name="sss" Click="sampleDropDown">s</Button>-->
<Label FontSize="18" FontFamily="Sans-serif" FontWeight="Light" Name="sam" Foreground="White" Margin="10">Samples</Label>
</StackPanel>
<StackPanel Orientation="Vertical" Name="sp_s">
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1">
<Image Source="pack://application:,,,/Resources/413.png" Height="40" Width="40" UseLayoutRounding="True" RenderTransformOrigin="-0.,0.558" MouseDown="reportDropDown" Cursor="Hand" Margin="5,0,0,0" Name="up_arrow1"/>
<Image Source="pack://application:,,,/Resources/412.png" Height="40" Width="40" UseLayoutRounding="True" Cursor="Hand" Margin="5,0,0,0" Name="down_arrow1" Visibility="Collapsed" MouseDown="reportDropDown"/>
<!--<Button Click="reportDropDown">r</Button>-->
<Label FontFamily="Sans-serif" FontWeight="Light" Foreground="White" FontSize="18" Margin="10">Reports</Label>
</StackPanel>
<StackPanel Orientation="Vertical" Name="sp_r">
</StackPanel>
</StackPanel>
</StackPanel>
</Border>
<StackPanel Width="1781">
<StackPanel Orientation="Horizontal" Background="#FFFDFDFD" Height="111">
<TextBox Name="sampleCount" Text="{Binding sampleCount, Source={StaticResource vmMain}, UpdateSourceTrigger=PropertyChanged}" Width="200"></TextBox>
<Button Cursor="Hand" Height="75" Width="75" Style="{StaticResource CircleButton}" FontFamily="Sans-Serif" FontSize="25" Foreground="White" Click="NewSample_Click" Content="+" Margin="20,0,0,0" Background="#FFACAABF" />
<StackPanel Margin="20,19,0,0">
<Image Source="pack://application:,,,/Resources/file512.png" Height="75" Width="75" UseLayoutRounding="True" Margin="0,0,0,0" MouseDown="CreateReport_Click" Cursor="Hand" SnapsToDevicePixels="True"/>
</StackPanel>
<Image Source="pack://application:,,,/Resources/play1.png" Height="75" Width="75" UseLayoutRounding="True" Margin="20,18,0,18" MouseDown="CreateReport_Click" Cursor="Hand" SnapsToDevicePixels="True"/>
<Image Source="pack://application:,,,/Resources/1131.png" Height="75" Width="75" UseLayoutRounding="True" Margin="1340,0,0,0" MouseDown="CreateReport_Click" Cursor="Hand"/>
</StackPanel>
<Frame x:Name="newSampleFrame" Content="" HorizontalAlignment="center" VerticalAlignment="center" Width="934" Height="456" NavigationUIVisibility="Hidden" RenderTransformOrigin="0.408,0.5" Visibility="Collapsed"/>
<Frame x:Name="reportFrame" Content="" HorizontalAlignment="Center" Height="842" VerticalAlignment="Center" Width="595" Margin="0,100,0,0" NavigationUIVisibility="Hidden"/>
<Frame x:Name="graphFrame" Content="" HorizontalAlignment="Center" Height="456" VerticalAlignment="Center" Width="934" NavigationUIVisibility="Hidden" Visibility="Collapsed"/>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
</Window>
MainViewModel.cs :
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ViewModel
{
public class MainViewModel : ObservableObject
{
public MainViewModel()
{
}
private string[] sampleName;
private string _sampleCount;
public Data obj2 = new Data();
public string this[int pos]
{
get
{
return sampleName[pos];
}
set
{
sampleName[pos] = value;
}
}
public string sampleCount
{
get
{
return _sampleCount;
}
set
{
if (value != _sampleCount)
{
_sampleCount = value;
OnPropertyChanged("sampleCount");
Console.WriteLine("Test");
Console.WriteLine(value);
obj2.sampleCount = value;
SaveFile.saveFileMain(obj2);
}
}
}
}
}
And I have the following code that create a textblock whenever I click on the OK button :
window2.xaml.cs:
private void Ok_Click(object sender, MouseButtonEventArgs e)
{
MainWindow win = (MainWindow)Application.Current.MainWindow;
int i = 1; // counter for the name of each new textblock
string name = String.Concat("sample", i);
// add textblok to the document list of new samples
if (File_name.Text != "")
{
TextBlock sampleText = new TextBlock();
sampleText.Text = File_name.Text;
sampleText.FontSize = 14;
sampleText.FontFamily = new FontFamily("Sans-serif");
sampleText.FontWeight = FontWeights.DemiBold;
sampleText.Margin = new Thickness(20,0,0,0);
sampleText.Name = name;
sampleText.PreviewMouseDown += new MouseButtonEventHandler(test1);
sampleText.Visibility = System.Windows.Visibility.Collapsed;
//binding
Binding myBinding = new Binding();
myBinding.Source =
myBinding.Path = new PropertyPath("sampleName");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
sampleText.SetBinding(TextBlock.TextProperty, myBinding);
Grid.SetColumn(sampleText, 0);
win.sp_s.Children.Add(sampleText);
// checking if the drop down of sample is already open, if so it will show the last textblock with pressing the arrow button.
var textblockSample = win.sp_s.Children.OfType<TextBlock>().FirstOrDefault();
if (textblockSample.Visibility == System.Windows.Visibility.Visible)
{
sampleText.Visibility = System.Windows.Visibility.Visible;
}
}
i += 1; // increasing the loop of names by 1
this.Close();
}
Is it possible to use the same object that is initiated in xaml (vmMain) as a source for binding the textblock (sample text) to sampleName property?
Not sure why you don't set DataContext of your MainWindow to MainViewModel.
<Window.DataContext>
<StaticResourceExtension ResourceKey="vmMain" />
</Window.DataContext>
Or, you can even set DataContext via MainWindow's code behind, which you don't seem to intent to not keep it untouched.
Then to set binding source:
myBinding.Source = this.DataContext;
In the case you refused to set the DataContext, you still can:
myBinding.Source = this.FindResource("vmMain") as MainViewModel;
Not sure if I managed to solve your problem.
Edit
I just realised your binding is in window2. You should do this:
myBinding.Source = win.DataContext;
Similarly, myBinding.Source = this.FindResource("vmMain") as MainViewModel; should also be changed to myBinding.Source = win.FindResource("vmMain") as MainViewModel;.
This is provided you still have that MainWindow win = (MainWindow)Application.Current.MainWindow; line there.
I believe that what you are looking for is the resources property:
myBinding.Source = Resources["vmMain"];
Resource allows you to access the XAML-defined (or otherwise) resources for the current object - the window.
You can also access the resources of any FrameworkElement in the same manner.
EDIT: I hadn't noted the fact that the vmMain was in a different class. With this in mind, no there is no way to reference that object directly from Window2 as there may be multiple MainWindows so you'd have to pick which MainWindow instance the vmMain should be taken from.
What you can do, however is create vmMain in your Application object (App.xaml). This would then share that object across all FrameworkElements in your application. To access this you could use
myBinding.Source = Application.Currennt.Resources["vmMain"];

WPF Move grid Error

I'm trying something new. I've got a few grids, and when I try to grab a grid i want to move its parent around my top grid. At the moment I get a System.NullReferenceException on m_startOffset = new Vector(translate.X, translate.Y); in the Grid_MouseDown method. Does someone know how i should tackle this problem?
UI:
<Grid x:Name="GridHost">
<Grid x:Name="GRLogin" Margin="1401,292,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="501" d:IsHidden="True" Focusable="True">
<Grid Height="30" VerticalAlignment="Top" Background="#FF1585B5" Margin="0" MouseLeftButtonUp="Grid_MouseUp" MouseLeftButtonDown="Grid_MouseDown" MouseMove="Grid_MouseMove" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="GRLoginClose" Content="X" Background="{x:Null}" Foreground="White" FontWeight="Bold" OpacityMask="Black" Margin="470,0,0,0" Width="30" Height="30" Click="Close"/>
<Button Content="-" Background="{x:Null}" Foreground="White" FontWeight="Bold" OpacityMask="Black" Margin="0,0,30,0" Width="30" Height="30" HorizontalAlignment="Right"/>
<Label Content="Login" HorizontalAlignment="Center" Margin="0" FontWeight="Bold"/>
</Grid>
<Grid HorizontalAlignment="Left" Height="250" Margin="0,30,0,0" VerticalAlignment="Top" Width="500" Background="#FF262626">
<PasswordBox HorizontalAlignment="Center" Margin="206,130,120,94" VerticalAlignment="Center" Width="174"/>
<Label Content="Password" HorizontalAlignment="Center" Margin="122,130,308,94" VerticalAlignment="Center" RenderTransformOrigin="-1.737,0.462" Width="70"/>
<Label Content="Username" HorizontalAlignment="Center" Margin="122,99,308,125" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Width="70"/>
<TextBox HorizontalAlignment="Center" Height="23" Margin="206,99,120,125" TextWrapping="Wrap" VerticalAlignment="Center" Width="174" RenderTransformOrigin="0.467,-0.346"/>
<Button Content="Login" HorizontalAlignment="Left" VerticalAlignment="Top" Width="258" Margin="122,180,0,0" Height="40" Background="#FF1585B5" Foreground="White" FontWeight="Bold"/>
</Grid>
</Grid>
Movement code:
private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = ((Grid)sender).Parent as Grid;
TranslateTransform translate = element.RenderTransform as TranslateTransform;
m_start = e.GetPosition(GridHost);
m_startOffset = new Vector(translate.X, translate.Y);
element.CaptureMouse();
}
private void Grid_MouseMove(object sender, MouseEventArgs e)
{
FrameworkElement element = ((Grid)sender).Parent as Grid;
TranslateTransform translate = element.RenderTransform as TranslateTransform;
if (element.IsMouseCaptured)
{
Vector offset = Point.Subtract(e.GetPosition(GridHost), m_start);
translate.X = m_startOffset.X + offset.X;
translate.Y = m_startOffset.Y + offset.Y;
}
}
private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = ((Grid)sender).Parent as Grid;
element.ReleaseMouseCapture();
}
Declare the parent Grid's RenderTransform in the XAML:
<Grid x:Name="GRLogin" Margin="1401,292,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="501" d:IsHidden="True" Focusable="True">
<Grid.RenderTransform>
<TranslateTransform/>
</Grid.RenderTransform>
...
</Grid>
You could also check the RenderTransform for null, in which case you set it: element.RenderTransform = new TranslateTransform();

Customize ListBox/ListView to "FlipView" (Picture)

I want to customize my listbox or listview to behave like the control on the following picture:
It's similar to FlipView but I've never worked with FlipView before and just saw some pictures.
I have found a good solution for me. It might helps somebody. I've changed it a little bit and It works perfectly for me.
http://www.codeproject.com/Articles/741026/WPF-FlipView
Try something like this
<UserControl x:Class="WpfApplication1.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<UserControl.Resources>
<DataTemplate x:Key="Test">
<Grid >
<Border Background="Red"
Loaded="RedBorder_OnLoaded" >
<!--content for this card goes here-->
<TextBlock Text="{Binding}"></TextBlock>
</Border>
<Border Background="Green"
Loaded="GreenBorder_OnLoaded"
Visibility="Collapsed" >
<!--content for this card goes here-->
<TextBlock Text="{Binding}"></TextBlock>
</Border>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListBox Name="myListbox"
Margin="50"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
ItemTemplate="{StaticResource Test}" />
<StackPanel Grid.Row="1"
HorizontalAlignment="Center"
Orientation="Horizontal">
<Button Width="20"
Height="20"
Background="Black"
Click="FirstButton_OnClick" />
<Button Width="20"
Height="20"
Background="Black"
Click="SecondButton_OnClick" />
</StackPanel>
</Grid>
</UserControl>
code behind
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
public partial class UserControl1 : UserControl
{
private readonly List<Border> redBorders = new List<Border>();
private readonly List<Border> greenBorders = new List<Border>();
public UserControl1()
{
InitializeComponent();
myListbox.ItemsSource = new List<string>() { "Batman", "Superman", "All others" };
}
private void RedBorder_OnLoaded(object sender, RoutedEventArgs e)
{
redBorders.Add(sender as Border);
}
private void GreenBorder_OnLoaded(object sender, RoutedEventArgs e)
{
greenBorders.Add(sender as Border);
}
private void FirstButton_OnClick(object sender, RoutedEventArgs e)
{
redBorders.ForEach(p => p.Visibility = Visibility.Visible);
greenBorders.ForEach(p => p.Visibility = Visibility.Collapsed);
}
private void SecondButton_OnClick(object sender, RoutedEventArgs e)
{
redBorders.ForEach(p => p.Visibility = Visibility.Collapsed);
greenBorders.ForEach(p => p.Visibility = Visibility.Visible);
}
}
}
usage
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfApplication1="clr-namespace:WpfApplication1">
<wpfApplication1:UserControl1 />
it's pretty simple, but i guess you can improve it from here.

Exception when databinding result from contact query in wp8 c#

I have been attempting to embed a contact picker within my windows phone 8 app. The idea is simple...show contacts, allow the user to tap the contacts they wish to save for use by my app, save selected items. Implementing this has not been as simple as i thought though.
I have the following code, mainly from MSDN samples:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Microsoft.Phone.UserData;
using System.Diagnostics;
namespace appNamespace
{
public partial class contact : PhoneApplicationPage
{
public contact()
{
InitializeComponent();
}
private void showContacts(object sender, RoutedEventArgs e)
{
Contacts cons = new Contacts();
//Identify the method that runs after the asynchronous search completes.
cons.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(Contacts_SearchCompleted);
//Start the asynchronous search.
cons.SearchAsync(String.Empty, FilterKind.None, "Contacts Test #1");
}
void Contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
{
//Do something with the results.
MessageBox.Show(e.Results.Count().ToString());
try
{
//Bind the results to the user interface.
ContactResultsData.DataContext = e.Results;
}
catch (System.Exception)
{
//No results
}
if (ContactResultsData.Items.Any())
{
ContactResultsLabel.Text = "results";
}
else
{
ContactResultsLabel.Text = "no results";
}
}
public void saveContacts(object sender, RoutedEventArgs e)
{
String strItem;
foreach (Object selecteditem in ContactResultsData.SelectedItems)
{
MessageBox.Show(selecteditem.ToString());
strItem = selecteditem as String;
ContactResultsLabel.Text = strItem;
System.Diagnostics.Debug.WriteLine(strItem);
MessageBox.Show("Saving " + strItem);
}
}
}
}
When running the code on a device, Lumia 920, the app shows the count of how many contacts, but does not show the databound list. (See XAML below) Instead, the app halts and an exception is thrown (ApplicationException, no details offered b debugger)
<phone:PhoneApplicationPage
x:Class="appNamespace.contact"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="appName" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="contacts" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,10" >
<TextBlock Name="ContactResultsLabel" Text="results are loading..." Style="{StaticResource PhoneTextLargeStyle}" TextWrapping="Wrap" />
<ListBox Name="ContactResultsData" ItemsSource="{Binding}" Height="436" Margin="12,0" SelectionMode="Multiple" >
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Name="ContactResults" Style="{StaticResource PhoneFontSizeMedium}" Text="{Binding Path=DisplayName, Mode=OneWay}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<Button x:Name="showButton" Content="Show Contacts" HorizontalAlignment="Left" VerticalAlignment="Top" Width="218" Height="90" Margin="0,531,0,0" Click="showContacts"/>
<Button x:Name="saveButton" Content="Save Contacts" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="238,531,0,0" Width="218" Height="90"/>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
Really hope someone can help, I cannot figure out why this exception arises. Thank you.
<TextBlock Name="ContactResults" Style="{StaticResource PhoneFontSizeMedium}" Text="{Binding Path=DisplayName, Mode=OneWay}" />
PhoneFontSizeMedium is, as the name indicates, a size. You can't apply it directly to a TextBlock.
What you're trying to do is:
<TextBlock Name="ContactResults" FontSize="{StaticResource PhoneFontSizeMedium}" Text="{Binding Path=DisplayName, Mode=OneWay}" />

data doesn't show on Text={Binding}?

Im quite new to silverlight and windows 7 phone development. And I'm not sure what I missed but apparantly I missed something because it's not working as intended.
My goal, is to show a list of creatures, with only their name and hitpoints. But the whole Text={Binding}-stuff apparently doesn't work. So I wonder if any of you guys could help me with this.
When i say it dosen't work, its because the data is in the creature list, but not in the page/textblocks - it shows the right amount of creatures, but just not the data.
XAML
<phone:PhoneApplicationPage
x:Class="RPG_Assistent.Pages.DamageTrackerPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<!--<Button Content="Damage" Height="72" HorizontalAlignment="Left" Margin="0,618,0,0" Name="btnDamage" VerticalAlignment="Top" Width="160" Click="btnDamage_Click" />
<TextBox Height="72" HorizontalAlignment="Left" Margin="158,618,0,0" Name="txtDamage" Text="" VerticalAlignment="Top" Width="286" KeyUp="NumericOnlyTextBox_KeyUp"></TextBox>-->
<ListBox ItemsSource="{Binding creatureList}" Height="500" HorizontalAlignment="Center" Margin="6,6,0,0" Name="listBox1" VerticalAlignment="Top" Width="400">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Width="400" Height="120" >
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="80" Width="200">
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Name:" Height="40"/>
<TextBlock Width="100" Text="{Binding Name}" Height="40"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Hitpoints:" Height="40"/>
<TextBlock Width="100" Text="{Binding HitPoints}" Height="40"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
<!--Sample code showing usage of ApplicationBar-->
<!--<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
<shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem Text="MenuItem 1"/>
<shell:ApplicationBarMenuItem Text="MenuItem 2"/>
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>-->
CS - called when page is done loading stuff in. ( called after InitializeComponent(); on my DamageTracker Page )
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace RPG_Assistent.Pages
{
public partial class DamageTrackerPage : PhoneApplicationPage
{
List<Models.Creature> creatureList { get; set; }
public DamageTrackerPage()
{
InitializeComponent();
creatureList = new List<Models.Creature>();
#region ApplicationTitle Setup
ApplicationTitle.Text = Constants.AppName;
ApplicationTitle.TextAlignment = Constants.AppName_TextAlignment;
ApplicationTitle.FontSize = Constants.AppName_FontSize;
ApplicationTitle.FontWeight = Constants.AppName_FontWeight;
#endregion
//SetInputScope(txtDamage);
LoadCreatures();
DataContext = this;
}
public void LoadCreatures()
{
string name;
for (int i = 0; i < 10; i++)
{
name = "Monster " + i + 1;
creatureList.Add(new Models.Creature(name));
}
}
public void btnDamage_Click(object sender, RoutedEventArgs e)
{
}
#region textbox control - makes numeric only
private void SetInputScope(TextBox textBoxControl)
{
InputScopeNameValue digitsInputNameValue = InputScopeNameValue.TelephoneNumber;
textBoxControl.InputScope = new InputScope()
{
Names = {
new InputScopeName()
{
NameValue = digitsInputNameValue
}
}
};
}
private void MaskNumericInput(TextBox textBoxControl)
{
string[] invalidCharacters = { "*", "#", ",", "(", ")", "x", "-", "+", " ", "#", "." };
for (int i = 0; i < invalidCharacters.Length; i++)
{
textBoxControl.SelectionStart = textBoxControl.Text.Length;
}
}
private void NumericOnlyTextBox_KeyUp(object sender, KeyEventArgs e)
{
MaskNumericInput((TextBox)sender);
}
#endregion
}
}
CS - Creature class, is placed in "Models" folder - because i thought i would be clever
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace RPG_Assistent.Models
{
public class Creature
{
public string Name { get; set; }
public int HitPoints { get; set; }
public string Type { get; set; }
public Creature(string name)
{
this.Name = name;
this.HitPoints = 0;
this.Type = "Images/mob.jpg";
}
public void Damage(int damage)
{
HitPoints += damage;
}
public void Bloodied()
{
switch (this.Type)
{
case "Images/mob.jpg":
this.Type = "Images/mobhurt.jpg";
break;
case "Images/mobhurt.jpg":
this.Type = "Images/mob.jpg";
break;
}
}
}
}
Since you are binding to a list of Creatures, you do not need to put Creature.Name. You should be able to change it to Text={Binding Name} and Text={Binding Hitpoints}
It looks like it should be Text={Binding Name} or Text={Binding HitPoints}
EDIT: but, Text={Binding Path=Name} or Text={Binding Path=HitPoints} would work too.
EDIT 2: Sorry, I didn't notice your comment. I don't have VS in the computer, so I can't try it myself, but try setting the DataType on the DataTemplate to Creature.
Update your binding to the following. I´ve dropped Creature, from the binding path. Then it should work
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Name:" Height="40"/>
<TextBlock Width="100" Text="{Binding Path=Name}" Height="40"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Hitpoints:" Height="40"/>
<TextBlock Width="100" Text="{Binding Path=HitPoints}" Height="40"/>
</StackPanel>
You always bind to the DataContext with direct bindings, and when setting the ItemsSource to a list, the DataContext becomes each item in the list for each row it will represent. So your thinking here is completely correct!
However: ContentControl act the same. When you set the Content of a ContentControl you basicly override the DataContext for the Content. The DataContext is thus set as your StackPanel, and it will render itself as your StackPanel, but you will also try to Bind to your StackPanel, and not to your Creature object anymore.
So you might want to do this:
Move your content StackPanel to a DataTemplate, set this DataTemplate as ContentTemplate on your Button and set the Content of the Button to a Binding of your Creature object, like so:
<Button Width="400" Height="120" Content="{Binding}">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Height="80" Width="200">
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Name:" Height="40"/>
<TextBlock Width="100" Text="{Binding Path=Name}" Height="40"/>
</StackPanel>
<StackPanel Orientation="Vertical" Height="40">
<TextBlock Width="100" FontSize="22" Text="Hitpoints:" Height="40"/>
<TextBlock Width="100" Text="{Binding Path=HitPoints}" Height="40"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
My preferred way of handling these occasions I set up a collection for the view. It would look something like this
public class CreatureList : ObservableCollection<Creature>
{
// at least implement the constructor
}
After that you can use the new collection class in your window XAML definition.
<ResourceDictionary>
<local:CreatureList x:Key="creatures" />
</ResourceDictionary>
The definition of the local namespace has to be set to the assembly namespace where the class CreatureList would be found. After that you can use the defined list in your listbox definition.
<ListBox Name="creatureListBox" ItemsSource="{Binding Source={StaticResource creatures}}">
<!-- Template definition for each entry -->
</ListBox>
To use these objects in your window class, you have to set up some attributes and associate them to the specified entry.
public partial class DamageTrackerPage : PhoneApplicationPage
{
private readonly CreatureList creatureList;
}
In the constructor of the class you bind the attribute to the specified XAML definition.
public DamageTrackerPage() {
InitializeComponent();
creatureList = FindResource("creatures") as CreatureList;
}
Now when you add entries to the list or remove entries from it the changes will be updated to your window automatically.
This is at least the way I'm doing it in WPF, but I'm sure for WinPhone apps that should be the same.

Categories