I have a question about Windows 10 UWP development using Visual Studio 2015.
I'm trying to use a DataTemplate for my GridView according to this tutorial. The problem I'm having is with my namespace.
I am not allowed to share my exact code for obvious reasons, but I'm wondering if one of you guys might have run into this before. I am getting almost the same error as this person (error code 0x09c4), except my DataTemplate is in my code-behind-file, not global like him/her. Along with that error I'm also getting the illusive "the _name does not exist in the namespace _namespace".
Here is a piece of my xaml file:
<Grid>
...
<GridView ItemsSource="{x:Bind ViewModel.AssessExItems}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:AssessExItem">
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Grid>
I know the DataTemplate is empty but even if I enter something there it still doesn't work. Here is my code-behind-file for this xaml file:
public sealed partial class AssessmentExample1Screen : Page
{
public AssessExItemViewModel ViewModel { get; set; }
public AssessmentExample1Screen()
{
this.InitializeComponent();
this.ViewModel = new AssessExItemViewModel();
}
}
public class AssessExItem
{
public int _assessment_id { get; set; }
public string name { get; set; }
public string surname { get; set; }
public string date { get; set; }
//public EmpAssessItem() { }
}
public class AssessExItemViewModel
{
private ObservableCollection<AssessExItem> exampleItems = new ObservableCollection<AssessExItem>();
public ObservableCollection<AssessExItem> AssessExItems { get { return this.exampleItems; } }
public AssessExItemViewModel()
{
//for (int i = 1; i < 3; i++)
//{
this.exampleItems.Add(new AssessExItem()
{
name = "Cat 777",
surname = "Botha",
date = "2015-03-22"
});
//}
this.exampleItems.Add(new AssessExItem()
{
name = "XZR 678",
surname = "Botha",
date = "2015-03-22"
});
this.exampleItems.Add(new AssessExItem()
{
name = "TBL 123",
surname = "Botha",
date = "2015-03-22"
});
}
}
Please help.
I reproduced your problem.
How to solve : Clean and build or rebuild the solution.And then I tested it,it works.
I guess the most possible reason of why it happened is build can update the file mainpage.g.cs which determined where to find the datatype.
<GridView ItemsSource="{x:Bind ViewModel.AssessExItems}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:AssessExItem">
<StackPanel Height="100" Width="100" Background="OrangeRed">
<TextBlock Text="{x:Bind name}"/>
<TextBlock Text="{x:Bind surname}" x:Phase="1"/>
<TextBlock Text="{x:Bind date}" x:Phase="2"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
Related
I am working on an App that selects Images and adds them to an Observablecollection. I want to show this collection in Xaml. There is no clear understandable answer that I have found so far.
in the MainPage:
public ObservableCollection<TimerWallpaper> timerWallpapers = new ObservableCollection<TimerWallpaper>();
And then the code for its class is this:
public class TimerWallpaper
{
public string timerFileName;
public BitmapImage timerImgSource;
public string timerTime;
public TimerWallpaper(string name, BitmapImage imgSource, int hours, int mins)
{
this.timerFileName = name;
this.timerImgSource = imgSource;
this.timerTime = hours.ToString() + " : " + mins.ToString();
}
}
Till this point it seems as the code is working.. the obstacle is with this code:
<GridView ItemsSource="x:Bind timerWallpapers">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:TimerWallpaper">
<Image Height="100" Width="100" Source="x:Bind timerImgSource"/>
<TextBlock Text="{x:Bind timerFileName}"/>
<TextBlock Text="{x:Bind timerTime}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I keep getting "Invalid Value" for the elements of the data templet.
What are the requirements to bind the GridView to the collection?
What is the correct format to do so?
OK, there are a number of problems with your code. First off, you should bind to properties, not fields, so your MainPage.cs should look something like this:
public sealed partial class MainPage : Page
{
public ObservableCollection<TimerWallpaper> TimerWallpapers { get; set; }
public MainPage()
{
this.InitializeComponent();
TimerWallpapers = new ObservableCollection<TimerWallpaper>();
DataContext = this;
}
}
and your TimerWallpaper like this:
public class TimerWallpaper
{
public string TimerFileName { get; set; }
public BitmapImage TimerImgSource { get; set; }
public string TimerTime { get; set; }
public TimerWallpaper(string name, BitmapImage imgSource, int hours, int mins)
{
this.TimerFileName = name;
this.TimerImgSource = imgSource;
this.TimerTime = hours.ToString() + " : " + mins.ToString();
}
}
(Or use private set if you want to)
Next, your binding syntax is wrong on a couple of lines where you forgot to enclose it in curly braces, and lastly, the DataTemplate can only have a single child, so you need to wrap your UI elements in a layout, e.g. a StackPanel, like so:
<GridView ItemsSource="{x:Bind TimerWallpapers}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:TimerWallpaper">
<StackPanel>
<Image Height="100" Width="100" Source="{x:Bind TimerImgSource}"/>
<TextBlock Text="{x:Bind TimerFileName}"/>
<TextBlock Text="{x:Bind TimerTime}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
I have searched the web for the last few days but can't seem to find something that I would have thought was quite a simple task. I would like to add a resource in my XAML page of my windows phone application which will reference a complex object but I can't find the correct method. Is this possible? Object is made up something similar to:
Public class ComplexClass
{
Public string name { get; set; }
Public int ID { get; set; }
Public observablecollection<SimpleClass> simpleObjects { get; set; }
Public addSimpleObject(SimpleClass newSimpleObject)
{
if (simpleObjects == null)
simpleObjects = new ObservableCollection<SimpleClass>();
simpleObjects.Add(newSimpleObject);
}
}
Public Class SimpleClass
{
Public String Name { get; set; }
Public String Disc { get; set; }
}
You could use MVVM do achieve this. There are already heaps of tutorials available that you can access to show you how to follow this design pattern, so I won't go into that.
Instead I'll just show you a simple way of getting the data to your view.
In the constructor of your UserControl (or Page or whatever), set up the DataContext to an instance of your ComplexClass:
ComplexClass complexClass;
public MyUserControl1()
{
complexClass = new ComplexClass();
complexClass.AddSimpleObject(new SimpleClass { Name = "Bob" });
this.DataContext = complexClass;
this.InitializeComponent();
}
Then in your XAML you can bind to it like this:
<StackPanel>
<!-- Binding to properties on ComplexClass -->
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding ID}" />
<ListView ItemsSource="{Binding SimpleObjects}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<!-- Binding to properties on SimpleClass -->
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Disc}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
Without knowing specifics of your code, it's hard for me to suggest a method that is most suitable for you. I'd read up on MVVM and view models.
<FlipView Name="flipView"
AutomationProperties.AutomationId="ItemsFlipView"
AutomationProperties.Name="Item Details"
TabIndex="1"
Grid.Row="1"
ItemsSource="{Binding}" Style="{StaticResource FlipViewStyle1}">
<TextBlock Name="answerT" Text="{Binding question}"/>
<FlipView.ItemContainerStyle>
<Style TargetType="FlipViewItem">
<Setter Property="Margin" Value="0,137,0,0"/>
</Style>
</FlipView.ItemContainerStyle>
<FlipView.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="flipTxt" Text="{Binding question}"/>
</DataTemplate>
</FlipView.ItemTemplate>
</FlipView>
I have the above FlipView in XAML defined. I want to get the information that i have in the "flipTxt" TextBlock in a string in C#.
Tried with VisualTreeHelper but i can't seem to understand exactly how it works.
As well, tried to create another textblock (answerT) that would read the same info and get the text from that one. Didn't work either.
Thanks
LE:
This is how i did the binding, i get the data from MobileService.
private IMobileServiceTable<myObj> obj_tb = App.MobileService.GetTable<myObj>();
private ObservableCollection<myObj> obj_it;
var res= await obj_tb.ToListAsync();
obj_it = new ObservableCollection<myObj(res);
flipView.ItemsSource = obj_it;
Providing your FlipView is binding to its collection correctly you can access the SelectedItem in code on different events eg SelectionChanged event
private void flipView_SelectionChanged(object sender, Windows.UI.Xaml.Controls.SelectionChangedEventArgs e)
{
if (flipView != null)
{
var item = flipView.SelectedItem as MyObj;
string question = item.Question;
string answer = item.Answer;
}
}
Possible MyObj
public class MyObj
{
public string Question { get; set; }
public string Answer { get; set; }
}
or as youre using MobileServices you would probably have this if using Json.NET
public class MyObj
{
[JsonProperty(PropertyName = "Question")
public string Question { get; set; }
[JsonProperty(PropertyName = "Answer")]
public string Answer { get; set; }
}
Following is the structure of my data:
public class TokenItems
{
public int ID { get; set; }
public int itemID { get; set; }
public string name { get; set; }
public int qty { get; set; }
public int twQty { get; set; }
public bool readyStatus { get; set; }
public Nullable<DateTime> orderOn { get; set; }
public int styleType { get; set; }
}
public class Token
{
public int tokenNo { get; set; }
public Nullable<DateTime> startedOn { get; set; }
public List<TokenItems> tokenItems { get; set; }
public bool readyStatus { get; set; }
public bool acceptStatus { get; set; }
}
The above structure fits well in the following DataTemplate. (It has multiple data template, DataTemplate within the DataTemplate)
TokenPanel has the data from Token class which is assigned from code behind like this:
TokenPanel.ItemsSource = List<Token> filledList;
tokenItems is assigned within the XAML:
ItemsSource = {Binding List<TokenItems> tokenItem}
The Template of tokenItems further contains the template of buttons which are created from the list items of the tokenItem.
I have applied custom style (redButton) to the button with Click event (listClick).
<ScrollViewer>
<ItemsControl x:Name="TokenPanel">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="0.119*"/>
<RowDefinition Height="0.881*"/>
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Text="{Binding tokenNo}" />
<StackPanel Grid.Row="1" Width="Auto" HorizontalAlignment="Stretch">
<ItemsControl Height="Auto" ItemsSource="{Binding tokenItems}" HorizontalAlignment="Stretch" Width="Auto">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Height="38" Width="Auto" Style="{StaticResource redButton}" HorizontalContentAlignment="Stretch" Click="listClick" >
<TextBlock Text= "{Binding name}"/>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" x:Name="tokenListBox" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
The program compiles well without any error. However when I update the TokenList it shows error with NullReference exception somewhere in XAML parsing.
I tried removing the Click event property from the XAML without any click event assigned. This executed program very well. But I can't click on the button which is the most thing I want. Further, I need custom style as well.
I am unable to figure out what the problem is... A quick fix will be highly appreciated.
EDIT:
This updates the tokenList;
public void update() {
List<TokenItems> tempList = new List<TokenItems>();
tokenList.Clear(); // clears previous items in tokenList;
while(database.Read()) {
tempList.Add(new Token() {
item= (int)database["item"]
});
}
var temp = new List<BumpBar.TokenItems>();
temp.AddRange(tokenModify(tempItems)); // modifies the items within the list
tempItems.Clear(); // clear to refill the tempItems
tempItems.AddRange(temp);
tokenList.Add(new Token() {
tokenNo = tokensList[i].tokenNo,
tokenItems = tempItems,
startedOn = tokensList[i].startedOn
});
}
Post the code that relates to this comment. I'm guessing you're accidentally nullify that token list.
The program compiles well without any error. However when I update the TokenList it shows
error with NullReference exception somewhere in XAML parsing.
I was trying to get it working for few days.
What is wrong in this code?
This is my window XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Rapideo_Client"
x:Class="Rapideo_Client.MainWindow"
Title="NVM" SnapsToDevicePixels="True" Height="400" Width="625">
<Window.Resources>
<DataTemplate x:Key="linksTemplate" DataType="DownloadLink">
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Path=Name}" FontWeight="Bold"></TextBlock>
<Label Content="{Binding Path=SizeInMB}"/>
<Label Content="{Binding Path=Url}"/>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Visible"
x:Name="MainListBox"
ItemTemplate="{DynamicResource linksTemplate}">
</ListView>
</Window>
This is my class:
class Rapideo
{
(...)
public List<DownloadLink> Links { get; private set; }
(...)
}
This is my item:
class DownloadLink
{
public string Name { get; private set; }
public string Url { get; private set; }
public DateTime ExpiryDate { get; private set; }
public float SizeInMB { get; private set; }
public int Path { get; private set; }
public string Value { get; private set; }
public LinkState State { get; set; }
public enum LinkState
{
Ready, Downloading, Prepering, Downloaded
}
public DownloadLink(string name, string url, DateTime expiryDate, float sizeInMB, int path, string value, LinkState state)
{
Name = name;
Url = url;
ExpiryDate = expiryDate;
SizeInMB = sizeInMB;
Path = path;
Value = value;
State = state;
}
}
This is my binding:
RapideoAccount = new Rapideo();
MainListBox.ItemsSource = RapideoAccount.Links;
Later in the code I populate that list in RapideoAccount.Links.
But nothing is showing in ListView.
List View is always empty.
Where is mistake in that code?
Yes, it should be an ObservableCollection<DownloadLink> if you're planning on adding to it AFTER you have setup the ItemsSource. If the list is preloaded and you won't be changing it, List<T> would have worked.
Now I do think that
MainListBox.ItemsSource = RapideoAccount.Links;
is still technically a binding. But what you are probably thinking of is binding via the DataContext rather than directly (al la MVVM style). So that'd be:
RapideoAccount = new Rapideo();
this.DataContext = RapideoAccount;
Then in your window, you'd bind your ItemSource like this:
<Window
...
<ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Visible"
x:Name="MainListBox"
ItemsSource="{Binding Links}"
ItemTemplate="{DynamicResource linksTemplate}">
</ListView>
</Window>
First off, you should use an ObservableCollection<DownloadLink> rather than a List<DownloadLink> if you're planning on making changes to the list after setting up the binding.
Second of all, just to be clear:
MainListBox.ItemsSource = RapideoAccount.Links;
is not a binding. You're just setting the property. That will work for certain scenarios, but its not really a binding like we normally talk about in WPF.
I think that Links needs to be an ObservableCollection, not a List.