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.
Related
I'm making an application using Caliburn.Micro(for easy data binding and stuff) and MahApps.Metro(for designing).
I've created a View name 'MainView' which has HamburgerMenu of MahApps.
My issue is data binding is working fine under HamburgerMenu.ContentTemplate tag
Here is my HamburgerMenu.ContentTemplate xaml.
<Page x:Class="Sample.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cal="http://www.caliburnproject.org"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:utils="clr-namespace:Omni.WindowsClient.Utils"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Omni.WindowsClient.Views"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="600">
<Page.Resources>
<DataTemplate x:Key="HamburgerMenuItem"
DataType="{x:Type mah:HamburgerMenuItem}">
<Grid Height="48">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Margin="12"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="{Binding Glyph}"
Stretch="UniformToFill" />
<TextBlock Grid.Column="1"
VerticalAlignment="Center"
FontSize="16"
Foreground="White"
Text="{Binding Label}" />
</Grid>
</DataTemplate>
</Page.Resources>
<Grid>
<mah:HamburgerMenu x:Name="HamburgerMenuControl"
SelectedIndex="0"
ItemTemplate="{StaticResource HamburgerMenuItem}"
OptionsItemTemplate="{StaticResource HamburgerMenuItem}"
IsPaneOpen="True"
DisplayMode="CompactInline"
cal:Message.Attach="[Event ItemClick] = [Action ShowDetails(HamburgerMenuControl.SelectedItem)]"
DataContext="{Binding RelativeSource={RelativeSource self}}">
<mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenuItemCollection>
<mah:HamburgerMenuItem Label="System Status">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Tasks" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem Label="Inbox">
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Inbox" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
<mah:HamburgerMenuItem.Tag>
<iconPacks:PackIconFontAwesome Width="22"
Height="22"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Kind="Certificate" />
</mah:HamburgerMenuItem.Tag>
</mah:HamburgerMenuItem>
</mah:HamburgerMenuItemCollection>
</mah:HamburgerMenu.ItemsSource>
<mah:HamburgerMenu.ContentTemplate>
<DataTemplate DataType="{x:Type mah:HamburgerMenuItem}">
<Grid utils:GridUtils.RowDefinitions="48,*">
<!--cal:Action.TargetWithoutContext="{Binding ElementName=HamburgerMenuControl, Path=DataContext}"-->
<Border Grid.Row="0"
Background="{DynamicResource MahApps.Metro.HamburgerMenu.PaneBackgroundBrush}">
<TextBlock x:Name="Header"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="24"
Foreground="White" />
<!--Text="{Binding Path=Header, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"-->
</Border>
<Frame Grid.Row="1"
cal:Message.Attach="RegisterFrame($source)"
DataContext="{x:Null}"
NavigationUIVisibility="Hidden" />
</Grid>
</DataTemplate>
</mah:HamburgerMenu.ContentTemplate>
</mah:HamburgerMenu>
</Grid>
</Page>
and respective view model code is:
using Caliburn.Micro;
using MahApps.Metro.Controls;
using System.Windows.Controls;
namespace Sample.ViewModels
{
public class MainViewModel : Screen
{
private readonly SimpleContainer _container;
private INavigationService _navigationService;
private string _header;
public string HeaderTitle
{
get { return _header; }
set
{
_header = value;
NotifyOfPropertyChange();
}
}
public MainViewModel(SimpleContainer container)
{
this._container = container;
DisplayName = "Main";
}
public void RegisterFrame(Frame frame)
{
_navigationService = new FrameAdapter(frame);
_container.Instance(_navigationService);
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
}
public void ShowDetails(HamburgerMenuItem menuItem)
{
switch (menuItem.Label)
{
case "System Status":
_navigationService.NavigateToViewModel(typeof(SystemStatusViewModel));
HeaderTitle = "System Status";
break;
case "Inbox":
_navigationService.NavigateToViewModel(typeof(InboxViewModel));
HeaderTitle = "Inbox";
break;
default:
break;
}
}
}
}
I want to change View in frame under HamburgerMenu.ContentTemplate when I click on menu item.
Like System Status view is SystemStatusView
and Inbox view is InboxView.
My code is working fine (it changes the view in frame and change the Header label too) if I don't use HamburgerMenu.ContentTemplate. But I want to use HamburgerMenu.ContentTemplate to work with HamburgerMenu.
Thanks!
If it's working fine if you don't use HamburgerMenu.ContentTemplate, but stops working when you do, the problem is probably with you overwriting the default template in a way that doesn't support all functionalities of a control.
I'd suggest you to use Blend to get the default HamburgerMenu.ContentTemplate, then just edit it to your needs, without changing too much (keep in mind that names of controls used as a template may have a crucial meaning, so be careful what you are editing).
If you don't know how to use Blend to get your control's template, here is a simple tutorial described in a documentation of Telerik controls (don't worry, it works the same for all controls). You just need to create copy of a HamburgerMenu.ContentTemplate, paste it to your application and you are good to go (editing).
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"];
I am working on windows phone app where I need to get the latest streams from a site. I currently made a custom control that can hold each item from JSON:
<UserControl x:Class="TwitchStationApp.StreamItem"
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"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
d:DesignHeight="195" d:DesignWidth="480">
<Grid x:Name="LayoutRoot" Height="195" Width="469">
<Image Height="156" HorizontalAlignment="Left" Margin="12,12,0,0" Name="imageChannel" Stretch="Fill" VerticalAlignment="Top" Width="156" />
<TextBlock Height="84" HorizontalAlignment="Left" Margin="174,48,0,0" Name="textBlockStatus" Text="TextBlock" VerticalAlignment="Top" Width="294" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,12,0,0" Name="textBlockChanelName" Text="TextBlock" VerticalAlignment="Top" Width="294" Foreground="#FFB0CB3E" />
<TextBlock Height="30" HorizontalAlignment="Left" Margin="174,138,0,0" Name="textBlockViewers" Text="TextBlock" VerticalAlignment="Top" Width="294" />
</Grid>
</UserControl>
So I will make a list of items List<Stream> _stream = new ..... So this list will be populated by lets say 10 items. For each item I need to make a User control (above) and add it to the ListBox so that users can scroll and select (click/tap) on the item they want to get more information about.
What is the best way to do this? I checked microsoft website and there is something about having ItemTemplate in a XAML file in <Window.Resource> tag but I dont know where and how to create this file and link it to the listbox I have.
This is typically done using a data template.
Assuming you have a collection of StreamTypes
public class StreamType
{
public string Title { get; set; }
public string Description { get; set; }
}
You can define a Data template in
Application wide – in app.xaml
Page Scope – on the page
Control container scope – local to the container of the listbox
Within the Listbox itself
To define it page wide:
<phone:PhoneApplicationPage.Resources>
<DataTemplate x:Key="SharedStreamTemplate">
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</phone:PhoneApplicationPage.Resources>
In your list box, assign the data template to the item template
<ListBox x:Name="lstStreams" ItemTemplate="{StaticResource SharedStreamTemplate}" />
If there isn't a plausible cause for you to re-use the template, just assign it directly in the listbox
<ListBox x:Name="lstStreams">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Title}" />
<TextBlock FontSize="{StaticResource PhoneFontSizeExtraLarge}" Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Update
In your code behind
// Constructor
public MainPage()
{
InitializeComponent();
BindStreams();
}
private void BindStreams()
{
lstStreams.ItemsSource = new List<StreamType>
{
new StreamType { Description = "Description One", Title = "Title One"},
new StreamType { Description = "Description Two", Title = "Title Two"},
new StreamType { Description = "Description Three", Title = "Title Three"},
};
}
That's right you need to use the ItemsControl.ItemTemplate property. Using this property, you can specify a template that will be applied to each item in the list. Here's sample code:
Model:
public class Model
{
public string Name { get; set; }
public Guid Id { get; set; }
}
XAML
<ListBox ItemsSource="{Binding Path=MyItemsSource}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text="{Binding Path=Id}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
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}" />
I have a ListBox in a popup. It’s bound to a simple Dictionary. I also have a ItemContainerStyle to theme listbox highlights. If I add ListBoxItems at design time, the selection style works, but the same style does not work when I assign ItemsSource. To troubleshoot I stripped it to barebones, and problem persists. Below is the code I have, Launch it, and click on ShowPopup to open Popup, first you will see items added in design time, and if you click on “Add ItemsSource” it will show run time items. You can see the selection in design time items, and not in run time items. (items generated via itemssource).
Any ideas? What am I missing?
<phone:PhoneApplicationPage
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"
xmlns:controls="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls"
x:Class="ObservableListSample.MainPage"
mc:Ignorable="d" d:DesignWidth="728" d:DesignHeight="480"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
shell:SystemTray.IsVisible="True"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="12,0,12,0">
<controls:Pivot Margin="8" Title="pivot">
<controls:PivotItem Margin="12" Header="Popup">
<Grid Margin="12">
<Button Content="Show Popup" Margin="1,0,0,0" VerticalAlignment="Bottom" Click="Button_Click"/>
</Grid>
</controls:PivotItem>
</controls:Pivot>
<Popup x:Name="LocPopup"
Margin="12,120,12,12">
<StackPanel Background="{StaticResource PhoneBackgroundBrush}"
Height="610"
Width="432">
<Button
Content="Add ItemsSource"
Click="Button_Click"
VerticalAlignment="Top" Margin="12" />
<ListBox x:Name="LibraryLocations" Height="480">
<ListBox.Resources> <DataTemplate x:Key="DataTemplate1">
<ListBoxItem Content="{Binding Value}" Tag="{Binding Key.Name}"/>
</DataTemplate>
</ListBox.Resources>
<ListBox.ItemTemplate>
<StaticResource ResourceKey="DataTemplate1"/>
</ListBox.ItemTemplate>
<ListBoxItem Content="ListBoxItem 1" />
<ListBoxItem Content="ListBoxItem 2" />
<ListBoxItem Content="ListBoxItem 3" />
<ListBoxItem Content="ListBoxItem 4" />
<ListBoxItem Content="ListBoxItem 5" />
<ListBoxItem Content="ListBoxItem 6" />
</ListBox>
</StackPanel>
</Popup>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
C#
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;
using System.Collections.ObjectModel;
namespace ObservableListSample
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (!LocPopup.IsOpen)
LocPopup.IsOpen = true;
else
{
Dictionary<string, string> items = new Dictionary<string, string>();
for (int i = 0; i < 20; i++)
{
items.Add(i.ToString(), "Item " + i.ToString());
}
if (LibraryLocations.ItemsSource == null)
LibraryLocations.Items.Clear();
LibraryLocations.ItemsSource = items;
}
}
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
if (LocPopup.IsOpen)
{
LocPopup.IsOpen = false;
e.Cancel = true;
}
else
{
base.OnBackKeyPress(e);
}
}
}
}
I don't see any ItemContainerStyle in your sample. Do you really need using ListBoxItem in the ListBox.ItemTemplate? Try this one instead:
<DataTemplate x:Key="DataTemplate1">
<TextBlock Text="{Binding Value}" Tag="{Binding Key.Name}"/>
</DataTemplate>