I'm trying to implement an application that requests weather data from OWM (OpenWeatherMap) and displays the temperature as well as an weather icon fitting the weather outside. OWM provides icon ids for the fitting icon. You can then access those icons over a specific web path. Displaying those icons in my app worked well. Because the icons provided by OWM have got a low resolution I decided to use vector graphics, that I saved in the application directory. Displaying those vector graphics directly using this code
<Image Source="Assets/WeatherIcons/01d.svg" Height="300" HorizontalAlignment="Right"/>
works just fine. But I want to adjust the used source depending on the, by OWM provided, icon id.
My Code at the moment looks like this:
MainPage.xaml:
<Page
x:Class="starting.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:starting"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="Black"
PointerPressed="WakeUp">
<StackPanel x:Name="WeatherInformation"
Visibility="Collapsed">
<Image x:Name="WeatherIcon"
Height="300"
HorizontalAlignment="Right"/>
<TextBlock Foreground="White"
TextAlignment="Center">
<Run x:Name="Temperature" FontSize="90"/>
<LineBreak/>
<Run x:Name="WeatherDescription" FontSize="50"/>
</TextBlock>
</StackPanel>
</Grid>
</Page>
MainPage.xaml.cs:
using System;
using System.Globalization;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media.Imaging;
namespace starting
{
public sealed partial class MainPage : Page
{
private DispatcherTimer modeTimer = new DispatcherTimer();
public MainPage()
{
this.InitializeComponent();
updateWeather(this, this);
modeTimer.Tick += new EventHandler<object>(Sleep);
modeTimer.Interval = new TimeSpan(0, 1, 0);
DispatcherTimer updateWeatherTimer = new DispatcherTimer();
updateWeatherTimer.Tick += new EventHandler<object>(updateWeather);
updateWeatherTimer.Interval= new TimeSpan(0, 30, 0);
updateWeatherTimer.Start();
}
private void updateWeather(object sender, object e)
{
WeatherApp.WeatherAPI myWeatherApi = new WeatherApp.WeatherAPI("Friedrichshafen,de");
OpenWeatherMapType.WeatherStream data = myWeatherApi.GetForecast();
WeatherIcon.Source = new BitmapImage(new Uri("ms-appx:///Assets/WeatherIcons/" + data.Weather[0].Icon + ".svg"));
Temperature.Text = Math.Round(data.Main.Temp).ToString() + "°C";
WeatherDescription.Text = data.Weather[0].Description;
}
private void Sleep(object sender, object e)
{
StandByTime.Visibility = Visibility.Visible;
ActiveTime.Visibility = Visibility.Collapsed;
WeatherInformation.Visibility = Visibility.Collapsed;
modeTimer.Stop();
}
private void WakeUp(object sender, PointerRoutedEventArgs e)
{
StandByTime.Visibility = Visibility.Collapsed;
ActiveTime.Visibility = Visibility.Visible;
WeatherInformation.Visibility = Visibility.Visible;
modeTimer.Start();
}
}
}
When I start the application there is no sign of an weather icon showing up. How's that possible?
It seems to be working fine like this:
MainPage.xaml:
<Page>
<Grid>
<Image Height="300">
<Image.Source>
<SvgImageSource x:Name="WeatherIconSource"/>
</Image.Source>
</Image>
</Grid>
</Page>
MainPage.xaml.cs:
private void updateWeather(object sender, object e)
{
WeatherApp.WeatherAPI myWeatherApi = new WeatherApp.WeatherAPI("Friedrichshafen,de");
OpenWeatherMapType.WeatherStream data = myWeatherApi.GetForecast();
WeatherIconSource.UriSource = new Uri("ms-appx:///Assets/WeatherIcons/" + data.Weather[0].Icon + ".svg");
}
Related
I have a question about finding resources in WPF, and I read the mechanism of finding resources from book.
It said that a UIElement will find its resources attribute first, if nothing fit then it will find its parent's resources attribute and so on, till application resources attribute.
I think it just like bubble routed event.
So I define a resource in stackpanel, here is the xaml.
<Window x:Class="DynamicResource.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:DynamicResource"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<StackPanel x:Name="stackPanel">
<StackPanel.Resources>
<TextBlock x:Key="res1" Text="this is staticresource" Background="Beige"></TextBlock>
<TextBlock x:Key="res2" Text="this is dynamicresource" Background="DarkGoldenrod"></TextBlock>
</StackPanel.Resources>
<Button Margin="5,5,5,0" Content="{StaticResource res1}"></Button>
<Button Margin="5,5,5,0" Content="{DynamicResource res2}"></Button>
<Button x:Name="button" Margin="5,5,5,0" Content="refresh resource" Click="Button_Click"></Button>
</StackPanel>
Then I try to change dynamic resource in the button click event, here is xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Can find target resource
//stackPanel.Resources["res1"] = new TextBlock() { Text = "this is new staticresource", Background = new SolidColorBrush(Colors.Tan) };
//stackPanel.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
//Can't find target resource
button.Resources["res1"] = new TextBlock() { Text = "this is new staticresource", Background = new SolidColorBrush(Colors.Tan) };
button.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
}
}
But the resource of button didn't change.
So what cause this happened, and how could to bubbly find resources.
you must set name for button and use this name in code behind
in xaml:
<Button Margin="5,5,5,0" Name="btnRes2" Content="{DynamicResource res2}"></Button>
in code behind :
private void Button_Click(object sender, RoutedEventArgs e)
{
btnRes2.Resources["res2"] = new TextBlock() { Text = "this it new dynamicresouce", Background = new SolidColorBrush(Colors.Magenta) };
}
this code work for DynamicResource.
Hello Stack Overflow community,
I am developing a weather application using the Universal Windows Platform.
I am also using openweathermap to collect my weather data and Json.Net to parse the Json data that the api returns.
I have designed my app with a navigation pane using a split view control and a frame.
Inside of the frame I have placed a relative panel. In the xaml code I have provided you can see the content I would like to place inside of the frame when the user clicks on the radio button.
What I need to do is fill out the function named CurrentWeather_Checked, it's currently empty, but I am not sure what I need to put in there to get the behavior that I want.
1.MainPage.xaml
<Page
x:Class="Susanoo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Susanoo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ThemesGeneric.xaml"/>
<ResourceDictionary Source="ThemesText.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<SplitView x:Name="NavigationPane" DisplayMode="CompactInline">
<SplitView.Pane>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="44" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="HamburgerButton" Grid.Row="0" Style="{StaticResource MenuItemButtonStyle}" Tag="" Click="HamburgerButton_Click" />
<StackPanel x:Name="NavigationMenu" Orientation="Vertical" Grid.Row="1" Background="#FF42424C">
<RadioButton x:Name="Option1"
GroupName="Group1"
Style="{StaticResource NavigationButtonStyle}"
Tag=""
Checked="CurrentWeather_Checked"
Content="Current Weather"
/>
<RadioButton x:Name="Option2"
GroupName="Group1"
Style="{StaticResource NavigationButtonStyle}"
Tag=""
Checked="Option2Button_Checked"
Content="Favorite Cities"
/>
</StackPanel>
</Grid>
</SplitView.Pane>
<SplitView.Content>
<Frame x:Name="Content" Background="#FF31A877">
<Frame.ContentTransitions>
<TransitionCollection>
<NavigationThemeTransition>
<NavigationThemeTransition.DefaultNavigationTransitionInfo>
<EntranceNavigationTransitionInfo/>
</NavigationThemeTransition.DefaultNavigationTransitionInfo>
</NavigationThemeTransition>
</TransitionCollection>
</Frame.ContentTransitions>
<RelativePanel x:Name="contentDisplay">
<TextBlock x:Name="cityName" Style="{StaticResource displayText}" RelativePanel.AlignHorizontalCenterWithPanel="True" Text="City"/>
<TextBlock x:Name="countryName" Style="{StaticResource displayText}" RelativePanel.AlignHorizontalCenterWithPanel="True" RelativePanel.Below="cityName" Text="Country"/>
<TextBlock x:Name="currentTemp" Style="{StaticResource displayText}" RelativePanel.AlignHorizontalCenterWithPanel="True" RelativePanel.AlignVerticalCenterWithPanel="True" Text="Temp"/>
<TextBlock x:Name="minTemp" Style="{StaticResource smallDisplayText}" RelativePanel.LeftOf="countryName" RelativePanel.Below="currentTemp" Text="Min"/>
<TextBlock x:Name="maxTemp" Style="{StaticResource smallDisplayText}" RelativePanel.RightOf="countryName" RelativePanel.Below="currentTemp" Text="Max"/>
</RelativePanel>
</Frame>
</SplitView.Content>
</SplitView>
</Page>
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
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.Navigation;
namespace Susanoo
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
ApplicationView.PreferredLaunchWindowingMode = ApplicationViewWindowingMode.PreferredLaunchViewSize;
// Set the min size to 550 * 600
ApplicationView.GetForCurrentView().SetPreferredMinSize(new Size { Width = 550, Height = 600 });
getCurrentWeather();
TitleBar();
}
async void getCurrentWeather()
{
WeatherObject currentWeather = new WeatherObject();
//units in Fahrenheit by default
currentWeather.Units = "Imperial";
//Searcy default for testing
currentWeather.RootObject.Name = "Searcy";
currentWeather.ZipCode = "72149";
await currentWeather.Task_getWeatherInfoByCityName();
//await currentWeather.Task_getWeatherInfoByZipCode();
if (currentWeather.RootObject != null)
{
cityName.Text = currentWeather.RootObject.Name;
countryName.Text = currentWeather.RootObject.Sys.Country;
currentTemp.Text = currentWeather.RootObject.Main.Temp.ToString();
if (currentWeather.Units == "Imperial")
{
currentTemp.Text = Math.Floor(currentWeather.RootObject.Main.Temp).ToString() + "° F";
minTemp.Text = "Low: " + Math.Floor(currentWeather.RootObject.Main.Temp_Min).ToString() + "°";
maxTemp.Text = "High: " + Math.Floor(currentWeather.RootObject.Main.Temp_Max).ToString() + "°";
}
else if (currentWeather.Units == "Metric")
{
currentTemp.Text = Math.Floor(currentWeather.RootObject.Main.Temp).ToString() + "° C";
minTemp.Text = "Low: " + Math.Floor(currentWeather.RootObject.Main.Temp_Min).ToString() + "°";
maxTemp.Text = "High: " + Math.Floor(currentWeather.RootObject.Main.Temp_Max).ToString() + "°";
}
//to use the images from openweathermap API
//not sure how to actually get it to show in the image in the main page?
string iconName = currentWeather.RootObject.Weather[0].Icon;
string imgUrl = "http://openweathermap.org/img/w/" + iconName + ".png";
//image.Source = imgUrl;
}
}
protected override void OnNavigatedTo(NavigationEventArgs args)
{
// Page was navigated to
var navManager = SystemNavigationManager.GetForCurrentView();
if (this.Frame.CanGoBack)
{
// Show Back button in title bar
navManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
}
else
{
// Remove Back button from title bar
navManager.AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed;
}
}
protected override void OnNavigatedFrom(NavigationEventArgs args)
{
// Page is being navigated away from
}
private void aboutButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(AboutPage));
}
private void TitleBar()
{
ApplicationViewTitleBar titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.BackgroundColor = Colors.Black;
titleBar.ForegroundColor = Colors.White;
titleBar.ButtonBackgroundColor = Colors.Black;
titleBar.ButtonForegroundColor = Colors.White;
}
public Frame AppFrame { get { return Content; } }
private void CurrentWeather_Checked(object sender, RoutedEventArgs e)
{
// Here is where I am expecting I need to put the code
}
private void Option2Button_Checked(object sender, RoutedEventArgs e)
{
}
private void HamburgerButton_Click(object sender, RoutedEventArgs e)
{
NavigationPane.IsPaneOpen = !NavigationPane.IsPaneOpen;
}
}
}
I am trying to make an application that switches between an image of the heads sign of a coin and the tails side of a coin. However, every time I press either the "heads" button or the "tails" button, an error occurs. How can I fix my code so that the image successfully switches?
XAML:
<Window x:Class="HeadsOrTails.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:HeadsOrTails"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Image
x:Name="coinImage"
HorizontalAlignment="Center"
Height="100"
Margin="43,10,374,209"
VerticalAlignment="Center"
Width="100"
Loaded="Image_Loaded"/>
<Button x:Name="tailsButton" Content="Show Tails" HorizontalAlignment="Center" Height="40" Margin="190,214,197,65" VerticalAlignment="Center" Width="130" Click="tailsButton_Click"/>
<Button x:Name="headsButton" Content="Show Heads" HorizontalAlignment="Center" Height="40" Margin="43,214,344,65" VerticalAlignment="Center" Width="130" Click="headsButton_Click"/>
<Button x:Name="exitButton" Content="Exit" HorizontalAlignment="Center" Height="40" Margin="339,214,48,65" VerticalAlignment="Center" Width="130" Click="exitButton_Click"/>
</Grid>
</Window>
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Media;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HeadsOrTails
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Image_Loaded(object sender, RoutedEventArgs e)
{
}
private void tailsButton_Click(object sender, RoutedEventArgs e)
{
//create a second bitmap image (tails)
BitmapImage c = new BitmapImage();
c.BeginInit();
c.UriSource = new Uri(#"C:\Users\Raymond\Documents\Visual Studio 2015\Projects\HeadsOrTails\tails.jpg");
c.EndInit();
var image = sender as Image;
image.Source = c;
}
private void headsButton_Click(object sender, RoutedEventArgs e)
{
//create the new bitmap image (heads)
BitmapImage b = new BitmapImage();
b.BeginInit();
b.UriSource = new Uri(#"C:\Users\Raymond\Documents\Visual Studio 2015\Projects\HeadsOrTails\heads.jpg");
b.EndInit();
var image = sender as Image;
image.Source = b;
}
private void exitButton_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
}
}
You can't use the sender argument, because that's the Button, not the Image control.
Use the coinImage member instead:
private void headsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = new BitmapImage(new Uri(#"C:\Users\Raymond Karrenbauer\Documents\Visual Studio 2015\Projects\HeadsOrTails\heads.jpg"));
}
private void tailsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = new BitmapImage(new Uri(#"C:\Users\Raymond Karrenbauer\Documents\Visual Studio 2015\Projects\HeadsOrTails\tails.jpg"));
}
Besides that, you should add both image files to your Visual Studio project, set their Build Action to Resource and access them by a Resource File Pack URI. This way you wouldn't have to deal with absolute file paths:
private void headsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = new BitmapImage(new Uri("pack://application:,,,/heads.jpg"));
}
private void tailsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = new BitmapImage(new Uri("pack://application:,,,/tails.jpg"));
}
You may then also add the BitmapImages as XAML Resources:
<Window ...>
<Window.Resources>
<BitmapImage x:Key="heads" UriSource="heads.png"/>
<BitmapImage x:Key="tails" UriSource="tails.png"/>
</Window.Resources>
...
</Window>
And use them like this:
private void headsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = (ImageSource)Resources["heads"];
}
private void tailsButton_Click(object sender, RoutedEventArgs e)
{
coinImage.Source = (ImageSource)Resources["tails"];
}
Clemens is absolutely right, and his second alternative is far superior because it doesn't re-load the bitmaps each time you flip them. However if I may suggest an even better alternative (IMHO) to what you're doing, instead of changing the Source of the coinImage each time, you might instead want to have two Images, for example, coinHeadsImage and coinTailsImage, and flip their respective Visibility properties in those Click handlers. Wrap both Images in their own common Grid so that they are overlapping in the visual tree. I'm not 100% certain, but I believe changing the Visibility of the Images would be more efficient speed-wise than setting the Source property, and either way, it would be better architecture because you could bind the Visibility properties directly to a hypothetical IsHeads property in your code-behind or view model, using appropriate converters of course.
Also, any time you use the as syntax, you generally should check the result for null. Unlike a simple type cast, you won't get an exception if the object cannot covert to the desired type when you use as. Had you checked for null you would have caught your error there.
I've found a weird problem in my app. When I open one of the pages, the app's InitializeComponent() method throws an XamlParseException. What can I do to get rid of this issue? I haven't found any obvious errors in my xaml code either. Here you can see my .cs and .xaml file of the page:
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 System.IO.IsolatedStorage;
namespace app_name
{
public partial class newsummaryPage : PhoneApplicationPage
{
List<String> savingList;
List<String> projectList;
List<String> subjectsList;
IsolatedStorageSettings settings;
Boolean amISelectingProjects = true;
Boolean firstSelection = true;
String practicesummaryText;
public newsummaryPage()
{
InitializeComponent();
//Initialize settings
settings = IsolatedStorageSettings.ApplicationSettings;
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
//Load existing list into the savingList (For temporary storage)
savingList = null;
savingList = readSetting("practiceList") != null ? (List<String>)readSetting("practiceList") : new List<String>();
//Remove existing practiceList from IsolatedStorage
settings.Remove("practiceList");
//Add the new practice summary to the savingList
savingList.Add(practiceTextBox.Text.ToString());
//Save the savingList into practiceList in IsolatedStorage
settings.Add("practiceList", savingList);
//Save the summary text itself. Add "-practicesummary" to the end of the name to be able to add it without conflicts with the projectList and it's references
settings.Add(practiceTextBox.Text.ToString() + "-practicesummary", practicesummaryText);
//Save the settings
settings.Save();
MessageBox.Show("next");
}
private void newsummaryPage_Loaded(object sender, RoutedEventArgs e)
{
//Initialize the list
projectList = new List<String>();
try
{
//Load existing list
selectprojectsandsubjectsListBox.Items.Clear();
projectList.Clear();
MessageBox.Show("loaded");
projectList = readSetting("projectList") != null ? (List<String>)readSetting("projectList") : new List<String>();
selectprojectsandsubjectsListBox.ItemsSource = projectList;
}
catch (Exception)
{
//run method CurrentProjectNotEmpty();
}
}
private static object readSetting(string key)
{
return IsolatedStorageSettings.ApplicationSettings.Contains(key) ? IsolatedStorageSettings.ApplicationSettings[key] : null;
}
private void selectprojectsandsubjectsListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
}
private void selectprojectsandsubjectsListBox_Tap(object sender, System.Windows.SizeChangedEventArgs e)
{
//Select a project/subject depending on the amISelectingProjects variable
if (amISelectingProjects.Equals(true))
{
//The user is selecting a project. Get the name from the project and use it to get the subjects
var selectedItem = selectprojectsandsubjectsListBox.SelectedItem as String;
String item = selectedItem;
MessageBox.Show("select");
subjectsList = readSetting(item) != null ? (List<String>)readSetting(item) : new List<String>();
selectprojectsandsubjectsListBox = null;
selectprojectsandsubjectsListBox.ItemsSource = subjectsList;
//Set amISelectingProjects to false so that the user can select subjects next time
amISelectingProjects = false;
//Set the ListBox to multiple selection mode for selecting multiple subjects
selectprojectsandsubjectsListBox.SelectionMode = SelectionMode.Multiple;
//Tell the user what he should do next
MessageBox.Show("The subjects corresponding the the project you selected will now appear in the list. Tap on all the items you want to create a summary of and then press create when you're finished.");
}
else if (amISelectingProjects.Equals(false))
{
//The user is selecting a subject. Select multipe
if (firstSelection.Equals(true))
{
practicesummaryText = selectprojectsandsubjectsListBox.SelectedItem as String;
firstSelection = false;
}
else if (firstSelection.Equals(false))
{
//This is not the first subject that the user selects, therefore add some characters in between
practicesummaryText = practicesummaryText + ". New subject= " + selectprojectsandsubjectsListBox.SelectedItem as String;
}
}
}
}
}
My xaml file:
<phone:PhoneApplicationPage
x:Class="app_name.newsummaryPage"
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="#FF03171B" Loaded="newsummaryPage_Loaded">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="1111"/>
<RowDefinition Height="0*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,0,0,0" Height="116" VerticalAlignment="Top">
<TextBlock Text="app name" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="New summary" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Grid x:Name="newsummaryGrid" Margin="0,116,12,370">
<TextBox x:Name="practiceTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" Width="458" Margin="0,27,0,0" Height="72" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="10,0,0,0" TextWrapping="Wrap" Text="Enter a new name for your summary:" VerticalAlignment="Top"/>
<Button x:Name="nextButton" Content="Create the summary" HorizontalAlignment="Left" Margin="0,553,0,0" VerticalAlignment="Top" Width="456" Click="nextButton_Click"/>
<ListBox x:Name="selectprojectsandsubjectsListBox" Margin="10,99,12,80" SelectionChanged="selectprojectsandsubjectsListBox_SelectionChanged" FontSize="36" Tap="selectprojectsandsubjectsListBox_Tap"/>
</Grid>
<!--ContentPanel - place additional content here-->
</Grid>
</phone:PhoneApplicationPage>
Inner exception:
$exception {System.Windows.Markup.XamlParseException: Failed to assign to property 'System.Windows.UIElement.Tap'. [Line: 32 Position: 172]
at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
at Knowledge_Organizer.newsummaryPage.InitializeComponent()
at Knowledge_Organizer.newsummaryPage..ctor()} System.Exception {System.Windows.Markup.XamlParseException}
See the output window, it usualy contains useful information about the exception's content.
or when the exception window appears, press break and go to visual studio DEBUG menu, choose windows->locals. the exception should appear in the locals view.
or try to debug and catch the exception, than see it's properties and inner message.
I'm trying to make KinectColorViewer to work with SDK 1.7 but without success. I can display video picture only if I manually copy pixels from camera to Image element.
I have the following XAML:
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:k="http://schemas.microsoft.com/kinect/2013"
xmlns:WpfViewers="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers" x:Class="KinectD.Camera"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500"
Title="Camera">
<Grid>
<k:KinectUserViewer k:KinectRegion.KinectRegion="{Binding ElementName=kinectRegion}" Height="100" HorizontalAlignment="Center" VerticalAlignment="Top" />
<k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" x:Name="sensorChooserUi" />
<k:KinectRegion x:Name="kinectRegion">
<Grid>
<k:KinectCircleButton Label="Menu" HorizontalAlignment="Right" Height="200" VerticalAlignment="Top" Click="MenuButtonOnClick" >
<StackPanel>
<Image Source="Images/smile.png" Height="30"/>
</StackPanel>
</k:KinectCircleButton>
</Grid>
</k:KinectRegion>
<WpfViewers:KinectColorViewer HorizontalAlignment="Left" Height="240" Margin="10,10,0,0" VerticalAlignment="Top" Width="320" Kinect="{Binding ElementName=sensorChooserUi, Mode=OneWay, Path=Kinect}"/>
</Grid>
And XAML.CS:
public partial class Camera : Page
{
#region "Kinect"
private KinectSensorChooser sensorChooser;
#endregion
public Camera()
{
this.InitializeComponent();
// initialize the sensor chooser and UI
this.sensorChooser = new KinectSensorChooser();
//Assign the sensor chooser with the sensor chooser from the mainwindow.
//We are reusing the sensorchoosing declared in the first window that can in contact with kinect
this.sensorChooser = Generics.GlobalKinectSensorChooser;
//subscribe to the sensorChooserOnKinectChanged event
this.sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
//Assign Kinect Sensorchooser to the sensorchooser we got from our static class
this.sensorChooserUi.KinectSensorChooser = sensorChooser;
// Bind the sensor chooser's current sensor to the KinectRegion
var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
BindingOperations.SetBinding(this.kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);
}
private void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
{
bool error = false;
if (args.OldSensor != null)
{
try
{
args.OldSensor.DepthStream.Range = DepthRange.Default;
args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
args.OldSensor.DepthStream.Disable();
args.OldSensor.SkeletonStream.Disable();
args.OldSensor.ColorStream.Disable();
}
catch (InvalidOperationException)
{
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
error = true;
}
}
if (args.NewSensor != null)
{
try
{
args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
args.NewSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
args.NewSensor.SkeletonStream.Enable();
}
catch (InvalidOperationException)
{
error = true;
// KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
// E.g.: sensor might be abruptly unplugged.
}
}
if (!error)
kinectRegion.KinectSensor = args.NewSensor;
}
private void MenuButtonOnClick(object sender, RoutedEventArgs e)
{
//Unsubscribe to the sensorchooser's event SensorChooseronkinectChanged
this.sensorChooser.KinectChanged -= SensorChooserOnKinectChanged;
(Application.Current.MainWindow.FindName("_mainFrame") as Frame).Source = new Uri("MainMenu.xaml", UriKind.Relative);
}
}
In tutorial I was following (http://channel9.msdn.com/Series/KinectQuickstart/Camera-Fundamentals) instructor just drops KinectColorViewer to a screen, sets path and it's working.
The KinectColorViewer available in the KinectWpfViewers assembly is used in the "Kinect Explorer" example, and that is the best place to see how it is used and behaves. From this example you will find that the proper way to initialize the viewer in the XAML and the bindings that are necessary.
From the code you posted, you appear to binding the Kinect itself (a reference to the hardware) to the KinectColorViewer, which is not what it is expecting. You need to be setting a reference to a KinectSensorManager class, which is part of the KinectWpfViewers assembly.
Here is a simplified XAML with a KinectColorViewer
<Window x:Class="Microsoft.Samples.Kinect.KinectExplorer.KinectWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Microsoft.Samples.Kinect.KinectExplorer"
xmlns:kt="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers"
Title="Kinect Explorer" Width="812" Height="768">
<Grid>
<kt:KinectColorViewer x:Name="ColorViewer" KinectSensorManager="{Binding KinectSensorManager}" CollectFrameRate="True" RetainImageOnSensorChange="True" />
</Grid>
</Window>
Then you XAML.CS constructor will look something similar to:
public KinectWindow()
{
this.viewModel = new KinectWindowViewModel();
// The KinectSensorManager class is a wrapper for a KinectSensor that adds
// state logic and property change/binding/etc support, and is the data model
// for KinectDiagnosticViewer.
this.viewModel.KinectSensorManager = new KinectSensorManager();
Binding sensorBinding = new Binding("KinectSensor");
sensorBinding.Source = this;
BindingOperations.SetBinding(this.viewModel.KinectSensorManager, KinectSensorManager.KinectSensorProperty, sensorBinding);
// Attempt to turn on Skeleton Tracking for each Kinect Sensor
this.viewModel.KinectSensorManager.SkeletonStreamEnabled = true;
this.DataContext = this.viewModel;
InitializeComponent();
}
Review the "Kinect Explorer" example for complete details.
I had the same problem with using KinectSensorManager. It turns out you need to call to Microsoft.Samples.Kinect.Wpf.Viewers and not just the kinect.dll, kinect.toolkit.dll, and kinect.controls.dll.
However, when I implemented KinectSensorManager, then the KinectUI and SensorChooser stopped working on my xaml interface.