Alternative Color for Gridview Row in Xamarin Forms - styles

I am trying to make alternative row color in Xamarin Gridview, unfortunately it is not working, can you anyone please see what mistake I am ding here.
I went through few articles and all they suggest to use converter to make alternative row color.
namespace CommonUI.Utilities
{
public class AlternatingHighlightColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Color rowcolor = Color.Transparent;
if (value == null || parameter == null) return Color.White;
var index = ((ListView)parameter).ItemsSource.Cast<object>().ToList().IndexOf(value);
if (index % 2 == 0)
{
rowcolor = Color.Pink;
}
return rowcolor;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:U="clr-namespace:CommonUI.Utilities"
x:Class="CommonUI.Views.MyProfile"
Title="My Profile" >
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" Padding="2" Spacing="10" BackgroundColor="#DCE4EA">
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Spacing="1">
<Grid BackgroundColor="#CFD9E1" Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="28"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="85"/>
<ColumnDefinition Width="45"/>
</Grid.ColumnDefinitions>
<Label Text="Aircraft" FontSize="13" TextColor="Black" Grid.Row="0" Grid.Column="0" XAlign="Start" YAlign="Center"/>
<Label Text="Date Created" FontSize="13" TextColor="Black" Grid.Row="0" Grid.Column="1" XAlign="Start" YAlign="Center"/>
<Label Text="Actions" FontSize="13" TextColor="Black" Grid.Row="0" Grid.Column="2" XAlign="Center" YAlign="Center"/>
</Grid>
<ListView x:Name="listView" ItemsSource="{Binding ProfileList}" SeparatorVisibility="Default" SeparatorColor="#DCE4EA">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="{Binding .,Converter={StaticResource U:AlternatingHighlightColorConverter}, ConverterParameter={x:Reference listView}}" Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>

Related

Xamarin Left margin in iPad

I face strange behavior when I am populate list view all cells have left margin
tested Device iPad 9 in simulator , iPad 12 in simulator
here is screen of my issue
and my second list
here is my Xaml
<customRender:ExtList x:Name="listViewFlights" BackgroundColor ="{StaticResource white_color}"
ItemTapped="ListView_OnItemTapped" SeparatorColor="Gray" SeparatorVisibility="Default"
MinimumHeightRequest="40" IsPullToRefreshEnabled="True" Refreshing="ListViewFlights_Refreshing" >
<ListView.ItemTemplate>
<DataTemplate>
<customRender:CustomViewCell >
<StackLayout Spacing="0" BackgroundColor="Aqua">
<Grid VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" x:Name="gridCell" RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3.25*"></ColumnDefinition>
<ColumnDefinition Width="4*"></ColumnDefinition>
<ColumnDefinition Width="4.75*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding FirstListColumn}" Style="{StaticResource GridItemStyleLabelStart_os}" Margin="10,0,0,0"/>
<StackLayout Grid.Row="0" Grid.Column="1" Padding="{Binding FlightListColumn2Padding}" VerticalOptions="Center" >
<Label Text="{Binding Dep_Dest}" Style="{StaticResource GridItemStyleLabel_os}" HorizontalTextAlignment="Start"></Label>
</StackLayout>
<Grid Grid.Row="0" Grid.Column="2" HorizontalOptions="FillAndExpand" RowSpacing="0" >
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.5*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
<ColumnDefinition Width="5.5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Frame Grid.Row="0" Grid.Column="0" IsVisible="{Binding IsRecalculated}" Padding="0" Margin="0,7" OutlineColor="#5C768E" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" HasShadow="False" BackgroundColor="Transparent">
<Label Text="R" Style="{StaticResource GridItemStyleLabelStart}" HorizontalOptions="CenterAndExpand" IsVisible ="{Binding IsRecalculated}" />
</Frame>
<Label Grid.Row="0" Grid.Column="1" Text="{Binding ATCCtot }" Style="{StaticResource GridItemStyleLabelStart}" TextColor="Red" HorizontalOptions="Start" />
<Label Grid.Row="0" Grid.Column="2" Text="{Binding PreparedStd}" Style="{StaticResource GridItemStyleLabelEnd_os}" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" />
</Grid>
<BoxView x:Name="SelectedBox" Grid.Row="0" Grid.Column="3" Opacity="{Binding IsSelected}" BackgroundColor="{StaticResource sub_header}" >
<BoxView.WidthRequest>
<OnIdiom x:TypeArguments="x:Double" Tablet="5" />
</BoxView.WidthRequest>
</BoxView>
</Grid>
</StackLayout>
</customRender:CustomViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</customRender:ExtList>
my tries to fix the issue :
after long search I find soluation in xamarin site , is to make custom render to my list view but it docent work
public class CustomListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.ListView> e)
{
base.OnElementChanged (e);
if (e.NewElement != null) {
var listView = Control as UITableView;
listView.CellLayoutMarginsFollowReadableWidth = false;
}
}
}
reference https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/viewcell/
This is a known bug that is in the process of being fixed.

UWP Accessing content in a data bound ListView

I have a ListView with a ListView.ItemTemplate if it is important: the ListView is part of a Grid). I will strip it down here for the minumum:
<ListView x:Name="lstFotos" Grid.Row="2" Grid.Column="1" Height="auto" Tapped="imageControl_Tapped" >
<ListView.ItemTemplate>
<DataTemplate>
<Grid IsTapEnabled="True" >
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image x:Name="imageControl" Width="200" Height="200" Source="{Binding DateiSoftwareBitmapSource}" IsTapEnabled="True" Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" />
<TextBlock x:Name="txtImageDateDescription" Text="Aufnahmedatum: " Grid.Column="1" Grid.Row="0" />
<TextBlock x:Name="txtImageDescriptionDescription" Text="Beschreibung: " Grid.Column="1" Grid.Row="1" />
<TextBlock x:Name="txtImageDate" Text="{Binding Datum}" Grid.Column="2" Grid.Row="0" />
<TextBox x:Name="txtImageDescription" Text="{Binding Beschreibung}" Grid.Column="2" Grid.Row="1" />
<Button x:Name="btnSpeichern" Content="Speichern" Grid.Column="3" Grid.Row="1" Click="btnSpeichern_Click" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In the code behing I do a
lstFotos.ItemsSource = AlleAnzeigeFotos
AlleAnzeigeFotos is a List(Of myClass), myClass contains the properties Datum, Beschreibung, DateiSoftwareBitmapSource.
What I want to do is that the user can edit the textfield, presses on the button and in the code behing I want to update the class and do some more stuff.
How can I get the appropriate instance of that class when I click the button?
UPDATE:
This is how it looks like:
"Beschreibung" (english: description) is empy after adding a foto and should be editable and stored by clicking "Speichern" (save).
(sender as Button).DataContext will give you the item which you clicked. Cast it to appropriate type of your class
update
Text="{Binding Beschreibung,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
var userenteredstring=((sender as Button).DataContext as your class).Beschreibung

Metro App Callisto Framework extend CustomDialog - Add TitleBackground

Does anyone know how to extend the CustomDialog control from Callisto metro app framework, to add a TitleBackground property?
Effectively, I would like to colour the Background of the row where the Title appears.
Figured it out:
In CustomDialog.cs add:
public Brush TitleBackground
{
get { return (Brush)GetValue(TitleBackgroundProperty); }
set { SetValue(TitleBackgroundProperty, value); }
}
public static readonly DependencyProperty TitleBackgroundProperty =
DependencyProperty.Register("TitleBackground", typeof(Brush), typeof(CustomDialog), null);
And then in Generic.xaml, go to the CustomDialog style and change the Grid definition to:
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle Grid.ColumnSpan="3" Grid.Row="0" Fill="{TemplateBinding TitleBackground}"/>
<Button Grid.Column="0" Grid.Row="0" x:Name="PART_BackButton" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,24,0,0" Style="{StaticResource DialogBackButtonStyle}" Command="{TemplateBinding BackButtonCommand}" CommandParameter="{TemplateBinding BackButtonCommandParameter}" Visibility="{TemplateBinding BackButtonVisibility}"/>
<local:DynamicTextBlock Grid.Column="1" Grid.Row="0" Foreground="{TemplateBinding TitleForeground}" x:Name="PART_Title" Text="{TemplateBinding Title}" FontFamily="Segoe UI" FontSize="26.6667" FontWeight="Light" Margin="0,0,0,8" />
<ContentPresenter Grid.Column="1" Grid.Row="1" Margin="0" x:Name="PART_Content" Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Background, Converter={StaticResource ColorContrast}}" />

Observable collection - CollectionChanged Binding

During programming, I ran into the following questions:
Does a observable collection implement a CollectionChanged event by itself? (Because of differentbooks refering to the fact that it does, but google shows otherwise)
I have the following code, and I want my UI to update by binding (the code is for windowsPhone 7.1) Also, the binding works for single items in my observable collection, but when I try to add a new object to my collection, the CollectionChanged event doesn't fire.
namespace Phone.lib.ViewModel
{
public class DeviceViewModel : ViewModelBase
{
DeviceModelInfo InfoList = new DeviceModelInfo();
public DeviceViewModel()
{
}
public DeviceViewModel(int index)
{
// Here I add a new item to the collection, But the ui only shows: Beckhoff, ver....
InfoList.Add(new DeviceInfo("name1", "name2", "name3"));
}
}
public class DeviceModelInfo : ObservableCollection<DeviceInfo>
{
public DeviceModelInfo() : base()
{
Add(new DeviceInfo("Beckhoff", "Ver. 1A2B3C", "Stopped"));
}
}
public class DeviceInfo : ViewModelBase
{
private string devicename;
private string deviceid;
private string devicestatus;
public DeviceInfo(string first, string second, string third)
{
devicename = first;
deviceid = second;
devicestatus = third;
}
public string DeviceName
{
get { return devicename; }
set
{
devicename = value;
RaisePropertyChanged("DeviceName");
}
}
public string DeviceID
{
get { return deviceid; }
set { deviceid = value; }
}
public string DeviceStatus
{
get { return devicestatus; }
set { devicestatus = value; }
}
}
Note: The class inherits from viewmodel base wich has the Inotify changed interface in it.
Code from my Xaml:
<phone:PhoneApplicationPage
x:Class="WindowsPhone.View.Device_Page"
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:ViewModel="clr-namespace:Phone.lib.ViewModel;assembly=Phone.lib"
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">
<!-- Static Resource area for binding -->
<phone:PhoneApplicationPage.Resources>
<ViewModel:DeviceModelInfo x:Key="deviceinfo"></ViewModel:DeviceModelInfo>
<ViewModel:DeviceModelSensor x:Key="devicesensors"></ViewModel:DeviceModelSensor>
<ViewModel:DeviceModelActuator x:Key="deviceactuators"></ViewModel:DeviceModelActuator>
</phone:PhoneApplicationPage.Resources>
<!-- 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="Kremer app" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource deviceinfo}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="100">
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=DeviceName, Mode=TwoWay}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceID, Mode=TwoWay}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceStatus, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Height="261" HorizontalAlignment="Left" Margin="-4,138,0,0" Name="Sensor_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource devicesensors}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=SensorName}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=SensorType}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Height="261" HorizontalAlignment="Left" Margin="-4,429,0,0" Name="Actuator_ListBox" ItemsSource="{Binding Source={StaticResource deviceactuators}}" VerticalAlignment="Top" Width="460">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="78" Margin="0,0,0,17" Width="432">
<TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=ActuatorName}" TextWrapping="Wrap" />
<TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=ActuatorType}" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
I hope someone is able to help me with this problem because i have been at this for like two days now.
Also, my apologies for my "bad" english, but english is not my native language
Cheers -Bart
EDIT: done a little test
I have run a little debugtest myself to see if the add operation adds to the right collection en therefor increments the count value
public DeviceViewModel(int index)
{
// Here I add a new item to the collection, But the ui only shows: Beckhoff, ver....
Debug.WriteLine("number of added items " + InfoList.Count.ToString());
InfoList.Add(new DeviceInfo("1", "2", "3"));
Debug.WriteLine("number of added items " + InfoList.Count.ToString());
InfoList.Add(new DeviceInfo("1", "2", "3"));
InfoList.Add(new DeviceInfo("1", "2", "3"));
InfoList.Add(new DeviceInfo("1", "2", "3"));
Debug.WriteLine("number of added items " + InfoList.Count.ToString());
}
output:
number of added items 1
number of added items 2
number of added items 5
Edit 2 (19-03-2012)
Last friday I tried to get it working like you suggested. But somehow the XAML can't find InfoList, and I don't know why. Maybe I do something wrong in the XAML itself or in the code behind or in the DeviceViewModel. So here is what I have at the moment:
DeviceViewModel:
namespace Phone.lib.ViewModel
{
public class DeviceViewModel : ViewModelBase
{
public DeviceModelInfo InfoList = new DeviceModelInfo();
public DeviceViewModel()
{
//DeviceModelInfo InfoList = new DeviceModelInfo();
InfoList.Add(new DeviceInfo("1", "2", "3"));
}
public DeviceViewModel(int index)
{
}
}
public class DeviceModelInfo : ObservableCollection<DeviceInfo>
{
public DeviceModelInfo() : base()
{
Add(new DeviceInfo("Beckhoff", "Ver. 1A2B3C", "Stopped"));
//this.CollectionChanged += (e, s) => { Debug.WriteLine("event Fired " + e.ToString()); };
}
}
public class DeviceInfo : ViewModelBase
{
private string devicename;
private string deviceid;
private string devicestatus;
public DeviceInfo(string first, string second, string third)
{
devicename = first;
deviceid = second;
devicestatus = third;
}
public string DeviceName
{
get { return devicename; }
set
{
devicename = value;
RaisePropertyChanged("DeviceName");
}
}
public string DeviceID
{
get { return deviceid; }
set { deviceid = value; }
}
public string DeviceStatus
{
get { return devicestatus; }
set { devicestatus = value; }
}
}
The code behind the page:
namespace WindowsPhone.View
{
public partial class Device_Page : PhoneApplicationPage
{
private DeviceViewModel _DV;
public Device_Page()
{
InitializeComponent();
_DV = new DeviceViewModel();
DataContext = _DV;
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
string selectedIndex = "";
if (NavigationContext.QueryString.TryGetValue("selectedItem", out selectedIndex))
{
int index = int.Parse(selectedIndex);
//_DV = new DeviceViewModel(index);
//DataContext = _DV;
Debug.WriteLine("index:" + index.ToString());
}
}
}
}
The XAML code:
<phone:PhoneApplicationPage
x:Class="WindowsPhone.View.Device_Page"
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:ViewModel="clr-namespace:Phone.lib.ViewModel;assembly=Phone.lib"
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">
<!-- Static Resource area for binding -->
<phone:PhoneApplicationPage.Resources>
<ViewModel:DeviceViewModel x:Key="deviceinfo"></ViewModel:DeviceViewModel>
<ViewModel:DeviceModelSensor x:Key="devicesensors"></ViewModel:DeviceModelSensor>
<ViewModel:DeviceModelActuator x:Key="deviceactuators"></ViewModel:DeviceModelActuator>
</phone:PhoneApplicationPage.Resources>
<!-- 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="Kremer app" Style="{StaticResource PhoneTextNormalStyle}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding InfoList}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="100">
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=DeviceName, Mode=TwoWay}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceID, Mode=TwoWay}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=DeviceStatus, Mode=TwoWay}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Height="261" HorizontalAlignment="Left" Margin="-4,138,0,0" Name="Sensor_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource devicesensors}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Width="432" Height="78">
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=SensorName}" />
<TextBlock TextWrapping="Wrap" Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=SensorType}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox Height="261" HorizontalAlignment="Left" Margin="-4,429,0,0" Name="Actuator_ListBox" ItemsSource="{Binding Source={StaticResource deviceactuators}}" VerticalAlignment="Top" Width="460">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Height="78" Margin="0,0,0,17" Width="432">
<TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextExtraLargeStyle}" Text="{Binding Path=ActuatorName}" TextWrapping="Wrap" />
<TextBlock Margin="12,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}" Text="{Binding Path=ActuatorType}" TextWrapping="Wrap" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
1) ObservableCollection implements the INotifyCollectionChanged interface, which defines the CollectionChanged event.
2) When you add a new item in DeviceViewModel you do it to a new instance of DeviceModelInfo, so a different instance than the one you declared in your XAML
<ViewModel:DeviceModelInfo x:Key="deviceinfo"></ViewModel:DeviceModelInfo>
You have to either bind to the DeviceModelInfo instance in DeviceViewModel
or use the instance of DeviceViewModel, declared in your XAML
Edit
In your XAML you have
That is the same as typing 'new DeviceModelInfo()' and then registering that instance in the resources of your control PhoneApplicationPage. And you bind the the ItemsSource of your ListBox to that particular instance.
ItemsSource="{Binding Source={StaticResource deviceinfo}}"
Now in your DeviceViewModel class you declare InfoList like this
DeviceModelInfo InfoList = new DeviceModelInfo();
You create a new instance of DeviceModelInfo, so InfoList is not the same instance/object as the instance/object in your XAML.
You must either
1) Bind your ItemsSource of the ListBox to the instance you have in DeviceViewModel. To do this you must first expose InfoList, that is make it public preferably through a property (but that's just convention, not required). Then make sure the DataContext of your control is set to the instance of DeviceViewModel your're working with. And then you can set the binding like this
ItemsSource="{Binding InfoList}"
Assuming InfoList is public
2) Get the instance deviceinfo created in your XAML like this:
DeviceViewModel deviceinfo = phoneApplicationPage.FindResource("deviceinfo") as DeviceViewModel;
assuming the instance of your control is called phoneApplicationPage. If you do it in the code behind of your control then phoneApplicationPage would be this.
And now you can pass this instance (deviceinfo) to your instance of DeviceViewModel.
From the naming I assume you're attempting to use the MVVM pattern, in which case you should go with 1)
Edit
Making the field public is good enough.
Now you need to bind it to the ItemsSource property of the ListBox. Which can be as simple as
ItemsSource="{Binding InfoList}"
But this requires that the DataContext property of your page (PhoneApplicationPage) is set to an instance of DeviceViewModel.
Without knowing exactly how you currently instantiate DeviceViewModel, it's hard for me to explain exactly how you can go about doing this. But I assume you instantiate DeviceViewModel in the code-behind of your page, so it looks something like this:
public partial class PhoneApplicationPage : Page
{
private DeviceViewModel _deviceViewModel;
//...
public PhoneApplicationPage()
{
InitializeComponent();
// I assume you do something like this
_deviceViewModel = new DeviceViewModel();
// You need to set the DataContext to the DeviceViewModel instance you have created.
DataContext = _deviceViewModel;
}
//...
}
Once you've made sure the DataContext is set to your DeviceViewModel instance then you can change the binding in your XAML like stated above.
So you should change the line
<ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding Source={StaticResource deviceinfo}}">
to
<ListBox Height="100" HorizontalAlignment="Left" Margin="-4,6,0,0" Name="Device_ListBox" VerticalAlignment="Top" Width="460" ItemsSource="{Binding ListInfo}">

Pop Up: a problem with margin Top

I'm developing a Windows Phone app.
I use a user control to show a pop up:
<UserControl x:Class="XXXXXXX.Views.Lists.GameDescriptionControl"
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}" Height="290" Width="460">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}" Margin="0,0,0,0" Width="460">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="133"/>
<RowDefinition Height="86"/>
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Center" Margin="10" Name="gameDescription" Text="" VerticalAlignment="Top" TextWrapping="Wrap" Grid.Row="1" Style="{StaticResource PhoneTextTitle3Style}" />
<Button Content="{Binding Path=AppResources.Yes, Source={StaticResource LocalizedStrings}}" Height="72" HorizontalAlignment="Left" Margin="50,5,0,0" Name="okButton" VerticalAlignment="Top" Width="160" Click="okButton_Click" Grid.Row="2" />
<Button Content="{Binding Path=AppResources.No, Source={StaticResource LocalizedStrings}}" Height="72" HorizontalAlignment="Left" Margin="244,5,0,0" Name="cancelButton" VerticalAlignment="Top" Width="160" Click="cancelButton_Click" Grid.Row="2" />
<TextBlock Grid.Row="0" x:Name="caption" HorizontalAlignment="Left" Margin="10" TextWrapping="Wrap" Text="{Binding Path=AppResources.Description, Source={StaticResource LocalizedStrings}}" Style="{StaticResource PhoneTextLargeStyle}"/>
</Grid>
</UserControl>
And this is the code to show the Pop Up:
private void showInfo(int gameId)
{
string gameDesc = getGameInfo(gameId);
p = new Popup();
GameDescriptionControl gd = new GameDescriptionControl();
gd.Description = gameDesc;
gd.OkClicked += new EventHandler(gd_OkClicked);
gd.CancelClicked += new EventHandler(gd_CancelClicked);
p.Child = gd;
// Set where the popup will show up on the screen.
p.VerticalOffset = 10;
p.HorizontalOffset = 10;
// Open the popup.
p.IsOpen = true;
}
But I get this:
As you can see, caption TextBlock hasn't got a margin top.
Any advice?
Margin will refer to the area outside of your textblock. If you want to move your text away from the edge of the textblock you will need to use the Padding attribute.
Not to act like the word paperclip, but it looks like you're trying to make a custom MessageBox.
Check this implementation out: http://cloudstore.blogspot.com/2011/01/customizing-messagebox-on-windows-phone.html . It's a great implementation of a messagebox that is very easy to use, looks/behaves very closely to the real MessageBox, and is lightweight.
Adding the few files that come with the solution, all you have to do is:
private MessageBoxService mbs = new MessageBoxService();
...
mbs.Closed +=new System.EventHandler(mbs_Closed);
mbs.Show("Confirm?","Are you sure you wish to do that?",MessageBoxServiceButton.YesNo,null);
void mbs_Closed(object sender, System.EventArgs e)
{
mbs.Closed -= mbs_Closed;
if (mbs.Result == MessageBoxResult.Yes)
{
...
}
}

Resources