I am using Callisto Toolkit to create a live hub tile in a Windows 8 application but I am not managing to perform data binding for my live tile. The code I am using is the following:
<callisto:LiveTile x:Name="liveTile2"
Background="#3B5998"
ItemsSource="{Binding Tile}"
Grid.Column="5"
Grid.Row="1"
Height="250"
VerticalAlignment="Top"
BorderBrush="White" BorderThickness="1"
Margin="5"
Direction="Up">
<callisto:LiveTile.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.DataContext>
<ViewModel:Tile/>
</Grid.DataContext>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="tileImage" Source="{Binding Image}"/>
<TextBlock Foreground="White"
TextWrapping="Wrap"
TextTrimming="WordEllipsis"
FontSize="14"
Grid.Row="1" Margin="0,71,0,0" Text="{Binding Msg}" />
</Grid>
</DataTemplate>
</callisto:LiveTile.ItemTemplate>
<callisto:LiveTile.DataContext>
<ViewModel:LiveTileData/>
</callisto:LiveTile.DataContext>
</callisto:LiveTile>
And this is the class for the tile:
namespace Test.ViewModel
{
public class Tile
{
public string Msg { get; set; }
public Uri Image { get; set; }
}
public class LiveTileData
{
private static ObservableCollection<Tile> tileData = new ObservableCollection<Tile>();
public static ObservableCollection<Tile> TileData
{
get
{
return tileData;
}
}
}
}
You are doing binding incorrectly. You should do binding LiveTile's ItemsSource as ObservableCollection<Tile> TileData. Moreover the DataContext is passed to the LiveTile itself not to its template. Check out the below code.
XAML
<callisto:LiveTile x:Name="liveTile2"
Background="#3B5998"
ItemsSource="{Binding TileData}"
Grid.Column="5"
Grid.Row="1"
Height="250"
VerticalAlignment="Top"
BorderBrush="White" BorderThickness="1"
Margin="5"
Direction="Up">
<callisto:LiveTile.ItemTemplate>
<DataTemplate>
<Grid Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image x:Name="tileImage" Source="{Binding Image}" Stretch="None"/>
<TextBlock Foreground="White"
TextWrapping="Wrap"
TextTrimming="WordEllipsis"
FontSize="14"
Grid.Row="1" Margin="0,71,0,0" Text="{Binding Msg}" />
</Grid>
</DataTemplate>
</callisto:LiveTile.ItemTemplate>
<callisto:LiveTile.DataContext>
<ViewModel:LiveTileData />
</callisto:LiveTile.DataContext>
</callisto:LiveTile>
C#
public class Tile
{
public string Msg { get; set; }
public Uri Image { get; set; }
}
public class LiveTileData
{
public LiveTileData()
{
tileData.Add(new Tile { Msg = "Stack Overflow", Image = new Uri("http://jenswinter.com/image.axd?picture=stackoverflow-logo-250.png") });
tileData.Add(new Tile { Msg = "Super User", Image = new Uri("http://superuser.com/content/superuser/img/logo.png") });
}
private static ObservableCollection<Tile> tileData = new ObservableCollection<Tile>();
public static ObservableCollection<Tile> TileData
{
get
{
return tileData;
}
}
}
Related
I have a WPF form that I want to use to manipulate a database table. To get the data out of the database I use Entity Framework Core. I try to follow the MVVM pattern.
So I have a Model called Employee with a number of string properties like Firstname and so on.
The form has a ListView that shows an ObservableCollection of Employee. Further I have a number of TextBoxes to display and manipulate the properties of single Employee objects. The selectedMemberPath of the ListView is bound to a property SelectedEmployee. The setter of SelectedEmployee than copies it's own properties to EditedEmployee. The TextBoxes are bound to EditedEmployee. The idea is, that I don't want to directly edit the ObservableCollection. This should only happen if a save button is clicked.
This is my view model.
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using XdcCore.Models;
using XdcCore.ViewModels.Commands;
namespace XdcCore.ViewModels
{
class EmployeeEditorVM : List<Employee>, INotifyPropertyChanged
{
public EmployeeSaveCommand EmployeeSaveCommand { get; set; }
public EmployeeEditorVM()
{
EmployeeSearch();
EmployeeSaveCommand = new EmployeeSaveCommand(this);
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private string employeeSearchText;
public string EmployeeSearchText
{
get { return employeeSearchText; }
set
{
employeeSearchText = value;
OnPropertyChanged("EmployeeSearch");
EmployeeSearch();
}
}
private Employee selectedEmployee;
public Employee SelectedEmployee
{
get { return selectedEmployee; }
set
{
selectedEmployee = value;
OnPropertyChanged("SelectedEmployee");
EditedEmployee = SelectedEmployee;
}
}
private Employee editedEmployee;
public Employee EditedEmployee
{
get { return editedEmployee; }
set
{
editedEmployee = value;
OnPropertyChanged("EditedEmployee");
}
}
private ObservableCollection<Employee> employees;
public ObservableCollection<Employee> Employees
{
get { return employees; }
set
{
employees = value;
OnPropertyChanged("Employees");
}
}
public void EmployeeSearch()
{
using (var context = new XdcContext())
{
if (employeeSearchText != null)
{
var _employees = context.Employee
.Where(x => x.Firstname.Contains(employeeSearchText));
Employees = new ObservableCollection<Employee>(_employees);
}
else
{
var _employees = context.Employee.Select(x => x);
Employees = new ObservableCollection<Employee>(_employees);
}
}
}
public void EmployeeSave()
{
using (var context = new XdcContext())
{
var entity = context.Employee.First(x => x.IdEmployee == SelectedEmployee.IdEmployee);
{
entity.Firstname = SelectedEmployee.Firstname;
entity.Lastname = SelectedEmployee.Lastname;
entity.Initials = SelectedEmployee.Initials;
context.SaveChanges();
}
EmployeeSearch();
}
}
}
}
this is my View:
<Window
x:Class="XdcCore.Views.Editors.EmployeeEditor"
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:local="clr-namespace:XdcCore.Views.Editors"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:XdcCore.ViewModels"
Title="Employee"
Width="800"
Height="450"
mc:Ignorable="d">
<Window.Resources>
<vm:EmployeeEditorVM x:Key="vm" />
</Window.Resources>
<Grid DataContext="{StaticResource vm}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="115*" />
<ColumnDefinition Width="277*" />
</Grid.ColumnDefinitions>
<!-- left column -->
<Border BorderBrush="DarkGray" BorderThickness="1">
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="aUTO" />
</Grid.RowDefinitions>
<Label
Grid.Row="0"
Margin="3,3,3,3"
Content="Filter:" />
<TextBox
x:Name="TextBoxSearch"
Grid.Row="1"
Height="25"
Margin="3,0,3,3"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Text="{Binding EmployeeSearchText, Mode=TwoWay}" />
<ListView
x:Name="ListViewOverview"
Grid.Row="2"
Margin="3,0,3,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding Employees, Mode=OneWay}"
SelectedItem="{Binding SelectedEmployee, Mode=OneWayToSource}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Initials}" />
<TextBlock Text=" : " />
<TextBlock Text="{Binding Firstname}" />
<TextBlock Text=" " />
<TextBlock Text="{Binding Lastname}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="ButtonDelete"
Grid.Column="0"
Height="25"
Margin="3,3,3,3"
Content="Delete"
IsEnabled="False" />
<Button
x:Name="ButtonNew"
Grid.Column="1"
Height="25"
Margin="3,3,3,3"
Content="Add New ..."
IsEnabled="True" />
</Grid>
</Grid>
</Border>
<!-- right Column -->
<Grid Grid.Column="1" Grid.ColumnSpan="2">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- right column, first row -->
<Border
Grid.Row="0"
BorderBrush="DarkGray"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
HorizontalAlignment="Right"
Content="First Name" />
<Label
Grid.Row="1"
Grid.Column="0"
HorizontalAlignment="Right"
Content="Last Name" />
<Label
Grid.Row="2"
Grid.Column="0"
HorizontalAlignment="Right"
Content="Initials" />
<Label
Grid.Row="3"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalContentAlignment="Center"
Content="ID" />
<Label
Grid.Row="4"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalContentAlignment="Center"
Content="RCU" />
<Label
Grid.Row="5"
Grid.Column="0"
HorizontalAlignment="Right"
VerticalContentAlignment="Center"
Content="RCT" />
<TextBox
x:Name="TextBoxFirstName"
Grid.Row="0"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Text="{Binding EditedEmployee.Firstname, Mode=TwoWay}" />
<TextBox
x:Name="TextBoxLastName"
Grid.Row="1"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Text="{Binding EditedEmployee.Lastname, Mode=TwoWay}" />
<TextBox
x:Name="TextBoxInitials"
Grid.Row="2"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
Text="{Binding EditedEmployee.Initials, Mode=TwoWay}" />
<TextBox
x:Name="TextBoxId"
Grid.Row="3"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
IsReadOnly="True" />
<TextBox
x:Name="TextBoxRCU"
Grid.Row="4"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
IsReadOnly="True" />
<TextBox
x:Name="TextBoxRCT"
Grid.Row="5"
Grid.Column="1"
Margin="0,3,3,3"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
HorizontalContentAlignment="Left"
VerticalContentAlignment="Center"
IsReadOnly="True" />
</Grid>
</Border>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button
x:Name="ButnSave"
Grid.Column="1"
Width="76"
Height="25"
Margin="60,3,60,0"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Command="{Binding EmployeeSaveCommand}"
Content="Save"
IsEnabled="True" />
</Grid>
<!-- Add new -->
</Grid>
</Grid>
</Grid>
</Window>
In other words: I want to click on an item in the list view, it's details are shown in the text boxes. I can change the text in the text boxes but the changes are not applied to the observable collection (or even database) until I click "save". The problem is, that exactly that happens: when I edit text in the text boxes the changes are also shown in the list view. And I can#t see why.
So, I got the concept of "copy vs point" of a variable wrong.
I had two solutions for my problem.
To my Employee model I added the method Copy:
public partial class Employee
{
public int IdEmployee { get; set; }
public string Initials { get; set; }
public string Firstname { get; set; }
public string Lastname { get; set; }
public string Rcu { get; set; }
public DateTime Rct { get; set; }
public Employee Copy()
{
return (Employee)this.MemberwiseClone();
}
}
Then I Changed my ViewModel so that EditedEmployee is a copy of SelectedEmployee
private Employee selectedEmployee;
public Employee SelectedEmployee
{
get { return selectedEmployee; }
set
{
selectedEmployee = value;
OnPropertyChanged("SelectedEmployee");
if (SelectedEmployee != null)
{
EditedEmployee = SelectedEmployee.Copy();
}
}
}
private Employee editedEmployee;
public Employee EditedEmployee
{
get { return editedEmployee; }
set
{
editedEmployee = value;
OnPropertyChanged("EditedEmployee");
}
}
The problem with this approach is, that if I mess around with the database and then need to run Scaffold-DbContext (I prefer the code-first approach of EFC) again, I would have to modify all models again. A solution to that might be some a second, modified Model that inherits from the original Model and then adds the Copy method.
My second approach is to bind the ListView via SelectedIndex instead of SelectedItem.
<ListView
...
ItemsSource="{Binding Employees, Mode=OneWay}"
SelectedIndex="{Binding SelectedItemIndex, Mode=TwoWay}">
In the ViewModel this is then represented by an int property. If this int is set (and >= 0) Employee gets copied EmployeeWorkingCopy. Furthermore if EmployeeWorkingCopy is set a single Employee dubbed EditedEmployee is set as the Employee of the working copy with the selected index.
private int selectedItemIndex;
public int SelectedItemIndex
{
get { return selectedItemIndex; }
set
{
selectedItemIndex = value;
if (SelectedItemIndex >= 0)
EmployeesWorkingCopy = new ObservableCollection<Employee>(Employees);
}
}
private Employee editedEmployee;
public Employee EditedEmployee
{
get { return editedEmployee; }
set
{
editedEmployee = value;
OnPropertyChanged("EditedEmployee");
}
}
private ObservableCollection<Employee> employeesWorkingCopy;
public ObservableCollection<Employee> EmployeesWorkingCopy
{
get { return employeesWorkingCopy; }
set
{
employeesWorkingCopy = value;
EditedEmployee = EmployeesWorkingCopy[SelectedItemIndex];
}
}
Thanks a lot for pointing out my misconception.
I have a Observable Collection, I want to Filter the collection. The Collection class like a dictionary. I have tried the following code But it is not filtering the collection. I know it is very basic question. I am new to c#. I am studying. Please any one help me to filter the collection. I have mentioned the code below, please refer
GroupModel
public class GroupModel
{
public string Key { get; set; }
public ObservableCollection<ValueModel> Values { get; set; }
}
ValueModel
public class ValueModel
{
public int Id { get; set; }
public string Name { get; set; }
}
ViewModel
Public Class ViewModel
{
public ObservableCollection<GroupModel> MainValues
{
get { return mainValues; }
set { mainValues = value; }
}
public string SearchIndicator
{
get { return searchIndicator; }
set
{
searchIndicator = value;
OnPropertyChanged(SearchIndicator);
ItemsView.Refresh();
}
}
public ViewModel(IMainValueCollection mainValueCollection)
{
MainValue = new ObservableCollection<GroupModel>();
this.MainValue = mainValueCollection;
ItemsView.Filter = new Predicate<object>(o => Filter(o as ValueModel));
}
public ICollectionView ItemsView
{
get
{
var value = (MainValues.SelectMany(a => a.Values)).ToList();
return CollectionViewSource.GetDefaultView((MainValues.SelectMany(a => a.Values)));
}
}
private bool Filter(ValueModel value)
{
if (SearchIndicator == null)
{
return true;
}
return value.Name.IndexOf(SearchIndicator, StringComparison.OrdinalIgnoreCase) != -1;
}
}
MainViewUI
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid
Grid.Row="0"
Height="35"
Margin="5,5,0,5">
<Border
Margin="10,10,10,0"
Padding="1"
BorderBrush="LightGray"
BorderThickness="1"
CornerRadius="0">
<Grid
Height="30"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid
Grid.Row="0"
Grid.Column="0"
Margin="2,0,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Image
Width="25"
Height="25"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Source="/Images/SearchIcon.png" />
</Grid>
<Grid
Name="TextBlockGrid"
Grid.Row="0"
Grid.Column="1"
Height="30"
HorizontalAlignment="Stretch"
VerticalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock
Padding="5,0,0,0"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Foreground="Gray"
Text="Search">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource MultiStringToVisibilityConverter}">
<Binding ElementName="searchBox" Path="Text.IsEmpty" />
<Binding ElementName="searchBox" Path="IsFocused" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<TextBox
x:Name="searchBox"
Width="{Binding ActualWidth, ElementName=TextBlockGrid}"
Padding="5,0,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Center"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
Text="{Binding SearchIndicator, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</Border>
</Grid>
<ItemsControl
Grid.Row="1"
MinWidth="150"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="White"
BorderThickness="0"
ItemsSource="{Binding MainValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Expander IsExpanded="True">
<Expander.Header>
<Grid>
<TextBlock x:Name="keys" Text="{Binding Key}" />
</Grid>
</Expander.Header>
<ListBox
Margin="15,0,0,0"
BorderThickness="0"
DisplayMemberPath="Name"
ItemsSource="{Binding Values}" />
</Expander>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
You are not binding to ItemsView at all.
Replace
ItemsSource="{Binding MainValues, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
with
ItemsSource="{Binding ItemsView}">
Also change the ItemsView implementation to
public ICollectionView ItemsView
{
get { return CollectionViewSource.GetDefaultView(MainValues); }
}
I am using the folloowing class but its not allowing me to display show_times in my xaml its just comming up
popcornpk.datamodel.fetchtiming
public class FetchTiming
{
public string id { get; set; }
public string theater_name { get; set; }
public string address { get; set; }
public List<string> show_times { get; set; }
public string screen_id { get; set; }
public string title { get; set; }
}
public class MovieDetail
{
public MovieDetails movie_details { get; set; }
public List<FetchTiming> fetch_timing { get; set; }
}
My Class call
public async Task<MovieDetail> GetMovieShowtimesAsync()
{
string jsonresult = await WCFRESTServiceCall("GET", "movie_details");
var jarray = JsonConvert.DeserializeObject<MovieDetail>(jsonresult);
return jarray;
}
This is my xamlmethod call I hav eno idea what is going on the data is being returned ok but I just cant seem to dispaly it
private async void listViewShowtimes_Loaded(object sender, RoutedEventArgs e)
{
popcornpk_Dal _dal = new popcornpk_Dal();
MovieDetail _showTimes = await _dal.GetMovieShowtimesAsync();
var listView = (ListView)sender;
listView.ItemsSource = _showTimes.fetch_timing.ToList();
}
Xaml Of DataTemplate
<PivotItem x:Name="pvtShowTimes" Header="showtimes">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="listViewShowtimes" ItemsSource="{Binding}" Loaded="listViewShowtimes_Loaded">
<DataTemplate>
<StackPanel Height="505">
<TextBlock FontSize="13" x:Name="txtshowtime" Text="{Binding theater_name}" HorizontalAlignment="Left" Margin="19,223,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="212" Foreground="White" Height="29" SelectionChanged="txtTtile_SelectionChanged"/>
<TextBlock FontSize="13" x:Name="txtshow_times" Text="{Binding address}" HorizontalAlignment="Left" Margin="19,223,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="212" Foreground="White" Height="29" SelectionChanged="txtTtile_SelectionChanged"/>
</StackPanel>
</DataTemplate>
</ListView>
</Grid>
</PivotItem>
Below is a screen shot of the app running on the device any help be greatly apreciated.
Ok So i have it at least displaying the thertre name which is good on the show times screen but its still not allowing me to display the show_times field.
<ListView x:Name="listViewShowtimes" ItemsSource="{Binding}" Loaded="listViewShowtimes_Loaded">
<ListView.ItemTemplate>
<DataTemplate>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock FontSize="13" Grid.Row="0" Grid.Column="0" x:Name="txtshowtime" Text="{Binding theater_name}" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="212" Foreground="White" Height="29" />
<TextBlock FontSize="13" Grid.Row="1" Grid.Column="0" x:Name="txtshow_times" Text="{Binding show_times}" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="212" Foreground="White" Height="29" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I think what i need to no is how to bind a list of strings through xaml Problem I have i need the show times to appear below the cinema name you see their
You have Text="{Binding show_times}" so In your class FetchTiming,
public List<string> show_times { get; set; }
is a list so if you bind it to a TextBlock, it will simply do ToString(). You have to add inside the template another ListView like:
<TextBlock FontSize="13" Grid.Row="0" Grid.Column="0" x:Name="txtshowtime" Text="{Binding theater_name}" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Top" Width="212" Foreground="White" Height="29" />
<ListView ItemsSource={Binding show_times} />
And will do the trick.
I am Working on Windows phone 8.1.I Making Simple ListView Demo Which is Contain two Image And Two TextBlock.
<ListView x:Name="lst1" Grid.ColumnSpan="2" >
<ListView.ItemTemplate>
<DataTemplate >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="imgSender" Source="Assets/button_register.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="8,15,8,8" />
<TextBlock Text="{Binding Sender}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,12,0,0"/>
<Image x:Name="imgReceiver" Source="Assets/button_register.png" Grid.Row="1" Stretch="None" VerticalAlignment="Top" Margin="4,0" />
<TextBlock Text="{Binding Receiver}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top"/>
<Image Source="Assets/scroll_line_addcategory.png" Grid.Row="2" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="4,8,4,0" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And My Problem is That I Want to Set the Visibility of 'imgSender' at Runtime in Xaml.cs File.
Is Anybuddy Have Any Idea For Access UI Control Contain by Data Template.
<ListView x:Name="lst1" Grid.ColumnSpan="2" >
<ListView.ItemTemplate>
<DataTemplate >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Visibility="{Binding SenderVisibility}" x:Name="imgSender" Source="Assets/button_register.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="8,15,8,8" />
<TextBlock Text="{Binding Sender}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,12,0,0"/>
<Image x:Name="imgReceiver" Source="Assets/button_register.png" Grid.Row="1" Stretch="None" VerticalAlignment="Top" Margin="4,0" />
<TextBlock Text="{Binding Receiver}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top"/>
<Image Source="Assets/scroll_line_addcategory.png" Grid.Row="2" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="4,8,4,0" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
And my Model Class is
public class User : INotifyPropertyChanged
{
private string sender = string.Empty;
private string receiver = string.Empty;
private string senderVisibility = string.Empty;
private string receiverVisibility = string.Empty;
public string Sender
{
get
{
return sender;
}
set
{
if (value != this.sender)
{
this.sender = value;
NotifyPropertyChanged("Sender");
}
}
}
public string Receiver
{
get
{
return this.receiver;
}
set
{
if (value != this.receiver)
{
this.receiver = value;
NotifyPropertyChanged("Receiver");
}
}
}
public string ReceiverVisibility
{
get
{
return this.receiverVisibility;
}
set
{
if (value != this.receiverVisibility)
{
this.receiverVisibility = value;
NotifyPropertyChanged("ReceiverVisibility");
}
}
}
public string SenderVisibility
{
get
{
return this.senderVisibility;
}
set
{
if (value != this.senderVisibility)
{
this.senderVisibility = value;
NotifyPropertyChanged("SenderVisibility");
}
}
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
If your ListView contains only one item you can easily subscribe to Loaded event of imgSender and then control it's Visibility.
private Image _imgSender;
void Image_Loaded(object sender, RoutedEventArgs e)
{
_imgSender = sender as Image();
}
void AnotherMethod()
{
if (_imgSender != null)
_imgSender.Visibility = Visibility.Collapsed;
}
EDIT
FOR MULTIPLE ITEMS
void HideImage(int elementIndex)
{
var container = lst1.ContainerFromIndex(elementIndex) as ListViewItem;
var imageSender = (container.Content as Grid).Children[0] as Image;
imageSender.Visibility = Visibility.Collapsed;
}
You can add a BooleanToVisibilityConverter
<Page.Resources>
<converter:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Page.Resources>
<ListView x:Name="lst1" Grid.ColumnSpan="2"
ItemsSource="{Binding TelecomCollection}">
<ListView.ItemTemplate>
<DataTemplate >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image x:Name="imgSender" Source="Assets/button_register.png" Stretch="None" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="8,15,8,8"
Visibility="{Binding ShowImgReceiver, Converter={StaticResource BooleanToVisibilityConverter}}"/>
<TextBlock Text="{Binding Sender}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Margin="0,12,0,0"/>
<Image x:Name="imgReceiver" Source="Assets/button_register.png" Grid.Row="1" Stretch="None" VerticalAlignment="Top" Margin="4,0" />
<TextBlock Text="{Binding Receiver}" FontSize="18" Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Grid.Row="1" VerticalAlignment="Top"/>
<Image Source="Assets/scroll_line_addcategory.png" Grid.Row="2" Stretch="None" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="4,8,4,0" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Then in your item class you can add ShowImgReceiver
public class Telecom
{
string Receiver {get; set;}
string Sender {get; set;}
bool ShowImgReceiver{get; set;}
}
In your binding class
public class ViewModel
{
public ObservableCollection<Telecom> TelecomCollection {get; set;}
}
If you want to make an item's image visibility Collapsed, then
TelecomCollection[0].ShowImgReceiver = false;
and to make it again Visible
TelecomCollection[0].ShowImgReceiver = true;
I'm pretty new to MVVM so bear with me.
I'm working on an application that contains a contacts list. I've defined a contact user control with the following model:
public class Client
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string PhoneNumber { get; set; }
public string Address1 { get; set; }
public string Address2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public int CustomerID { get; set; }
public string FullName
{
get
{
string result = FirstName;
if (string.IsNullOrEmpty(result))
result = MiddleName;
else if(!string.IsNullOrEmpty(MiddleName))
result += string.Format(" {0}", MiddleName);
if (string.IsNullOrEmpty(result))
result = LastName;
else if (!string.IsNullOrEmpty(LastName))
result += string.Format(" {0}", LastName);
if (string.IsNullOrEmpty(result))
result = "";
return result;
}
}
}
And the following ViewModel:
public class ClientViewModel : ObservableObject
{
public Client Customer
{
get
{
return _customer;
}
set
{
_customer = value;
RaisePropertyChangedEvent("Customer");
}
}
public string FullName { get { return _customer.FullName; } }
public string PhoneNumber { get { return _customer.PhoneNumber; } }
public string Address1 { get { return _customer.Address1; } }
public string Address2 { get { return _customer.Address2; } }
public string City { get { return _customer.City; } }
public string State { get { return _customer.State; } }
public string ZipCode { get { return _customer.ZipCode; } }
Client _customer = new Client();
}
And the following View:
<UserControl x:Class="LawnCareManager.Views.ClientView"
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:local="clr-namespace:LawnCareManager.ViewModels"
mc:Ignorable="d"
d:DesignHeight="180" d:DesignWidth="300">
<UserControl.DataContext>
<local:ClientViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="Name: "/>
<Label Grid.Row="0"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding FullName}"/>
<Label Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="Phone Number: "/>
<Label Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding PhoneNumber}"/>
<Label Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="Address 1: "/>
<Label Grid.Row="2"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding Address1}"/>
<Label Grid.Row="3"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="Address 2: "/>
<Label Grid.Row="3"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding Address2}"/>
<Label Grid.Row="4"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="City: "/>
<Label Grid.Row="4"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding City}"/>
<Label Grid.Row="5"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="State: "/>
<Label Grid.Row="5"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding State}"/>
<Label Grid.Row="6"
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
Margin="10,0,0,0"
Content="Zip Code: "/>
<Label Grid.Row="6"
Grid.Column="1"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10,0,0,0"
Content="{Binding ZipCode}"/>
</Grid>
</UserControl>
Now, I want to create a user control that contains a list of contacts defined in the ViewModel below:
public class ClientsListViewModel : ObservableObject
{
public ObservableCollection<ClientViewModel> Clients
{
get { return _clients; }
set { _clients = value; }
}
ObservableCollection<ClientViewModel> _clients = new ObservableCollection<ClientViewModel>();
public ClientsListViewModel()
{
ClientViewModel client = new ClientViewModel();
client.Customer.FirstName = "John";
client.Customer.LastName = "Doe";
client.Customer.PhoneNumber = "555-555-5555";
client.Customer.Address1 = "1234 Fake Street";
client.Customer.City = "Springfield";
_clients.Add(client);
}
}
And the View below:
<UserControl x:Class="LawnCareManager.Views.ClientsListView"
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:local="clr-namespace:LawnCareManager.ViewModels"
xmlns:views="clr-namespace:LawnCareManager.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<local:ClientsListViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Label Content="Contacts"
Grid.Row="0"
Grid.Column="0"/>
<ListView Grid.Column="1" Grid.Row="2" Grid.ColumnSpan="2" ItemsSource="{Binding Clients}" x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<views:ClientView DataContext="{Binding}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</UserControl>
The problem is that the ClientView ListViewItems in the ClientsListView are not binding correctly to the ObservableCollection of ClientViewModels. The correct number of ClientViews shows up in the list if I add more ClientViewModels, but none of the labels in the ClientView are populating.
Could somebody tell me what I'm doing wrong? Any feedback is greatly appreciated!
The issue here is that you are constructing the data context for client view within the InitializeComponent method. That's due to the static declaration in your Xaml. You can prove this empirically by adding this line of code to the ClientView constructor...
var dc = this.DataContext;
and observe that it gets created with null values at the "Wrong time".
If you change these lines in your ClientView.xaml...
<UserControl.DataContext>
<genericMvvm1:ClientViewModel/>
</UserControl.DataContext>
to this...
<!--<UserControl.DataContext>
<genericMvvm1:ClientViewModel/>
</UserControl.DataContext>-->
You will see your clients getting populated and displayed the way you were expecting. You'll need to change your design strategy to take account of the way InitializeComponent behaves, but this answer gets you 'unstuck'.