XAML Binding on UserControl - xamarin.ios

I currently have a user control
<?xml version="1.0" encoding="utf-8" ?>
<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Mobile.Control.MultiSelect">
<ListView ItemsSource="{Binding ListSource}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<ContentView Padding="10">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Name}" HorizontalOptions="Center" TextColor="White" />
</StackLayout>
</ContentView>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
In the code behind I have
public partial class MultiSelect : StackLayout
{
public MultiSelect()
{
InitializeComponent();
BindingContext = this;
}
public static readonly BindableProperty ListSourceProperty =
BindableProperty.Create<MultiSelect, ObservableCollection<ListItem>>(p => p.ListSource, new ObservableCollection<ListItem>());
public ObservableCollection<ListItem> ListSource
{
get { return (ObservableCollection<ListItem>)GetValue(ListSourceProperty); }
set { SetValue(ListSourceProperty, value); }
}
}
In my XAML page I then have
<control:MultiSelect x:Name="MyMultiSelect" />
The question is, how do I bind something in the BindingContext of the XAML
page to the user control.
In the code behind of the XAML page I have
MyMultiSelect.ListSource = BindingContext.MyList;
and this works well. However I don't want anything in the code behind of my XAML page as it goes against the nice clean MVVM pattern I have going on, where my code behind is otherwise nice, clean and empty.
In XAML I have tried
and quite a few other variants but can't get anything to work.

Try this:
public static readonly BindableProperty ListSourceProperty =
BindableProperty.Create<MultiSelect, ObservableCollection<ListItem>>(p => p.ListSource, new ObservableCollection<ListItem>(), BindingMode.Default, null, (bindable, oldVal,newVal)=>{ (bindable as MultiSelect).LisstSource = newVal;});

Related

Shopping Cart Quantity not getting incremented

We are developing an iOS shopping cart application in c# and visual studio for xamarin we are using listview for displaying items and quantity text box, next to the quantity entry box we placed two button plus and minus to increase and decrease the quantity.
We are able to see the quantity and the button in the listview, but when we click on + button quantity is not getting incremented and same with - button.
Request you to help us to resolve this issue and we are pasting code below
c# code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Collections.ObjectModel;
using ShopApp.Models;
using System.Reflection;
using System.IO;
using ShopApp.Views;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Windows.Input;
namespace ShopApp.SalesOrderPages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AllItems : ContentPage
{
ObservableCollection<Catalogcls> employees = new ObservableCollection<Catalogcls>();
public AllItems()
{
InitializeComponent();
var assembly = typeof(LoadResourceText).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("ShopApp.Catalog_Master.json");
Catalogcls[] CatalogObj;
using (var reader = new StreamReader(stream))
{
var json = reader.ReadToEnd();
var jsondeserilize = JsonConvert.DeserializeObject<RootObject2>(json);
CatalogObj = jsondeserilize.Catalog;
}
for (int i = 0; i < CatalogObj.Length; i++)
{
employees.Add(new Catalogcls
{
Image = CatalogObj[i].Image,
Name = CatalogObj[i].Name,
Pack = CatalogObj[i].Pack,
Price = CatalogObj[i].Price,
UnitPrice = CatalogObj[i].UnitPrice
});
lstView.ItemsSource = employees;
}
}
}
}
Models
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShopApp.Models
{
public class Catalogcls
{
public string Type { get; set; }
public string Image { get; set; }
public string Name { get; set; }
public double UnitPrice { get; set; }
public string Price { get; set; }
public string Pack { get; set; }
}
public class RootObject2
{
public Catalogcls[] Catalog { get; set; }
}
}
Xaml code
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ShopApp.SalesOrderPages.AllItems">
<StackLayout Orientation="Vertical">
<Label Text="ListView" FontSize="60" ></Label>
<ListView x:Name="lstView" HasUnevenRows="True" >
<ListView.Header>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" >
<StackLayout Orientation="Vertical" HorizontalOptions="EndAndExpand" >
<Label Text="Total:" FontSize="15" TextColor="Black" />
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="EndAndExpand" Padding="0,0,20,0">
<Image Source="cart.png" x:Name="CartImage" Opacity="0.5" AnchorX="0.5" AnchorY="0.5" HeightRequest="40">
</Image>
<Button WidthRequest="100" HeightRequest="20" Text="Nextpage"></Button>
</StackLayout>
</StackLayout>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" >
<Grid Padding="20">
<Image Source="{Binding Image}" WidthRequest="100" HeightRequest="100"/>
</Grid>
<StackLayout Orientation="Vertical" Padding="20" >
<StackLayout>
<Label Text="{Binding Name}" FontSize="15" TextColor="Black" />
<Label Text="{Binding Price}" FontSize="15" TextColor="Black" />
<Label Text="{Binding Pack}" FontSize="15" TextColor="Black" />
<Label Text="{Binding UnitPrice}" FontSize="15" TextColor="Black" />
</StackLayout>
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
<StackLayout Orientation="Vertical">
<Button WidthRequest="60" HeightRequest="20" Text="-" Command="{Binding DecreaseQuantityCommand}" TextColor="Black"></Button>// on click of - button not able bind value for entrybox
</StackLayout>
<StackLayout Orientation="Vertical" >
<Entry WidthRequest="40" HeightRequest="20" Text="{Binding Quantity, Mode=TwoWay}" ></Entry>
</StackLayout>
<StackLayout Orientation="Vertical">
<Button WidthRequest="60" HeightRequest="20" Text="+" Command="{Binding IncreaseQuantityCommand}" TextColor="Black" ></Button>
</StackLayout>
</StackLayout>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

How to add humburger icon in MasterDetailPage in xamarin.Forms(iOS)

I am new to Xamarin.Forms. I am creating NavigationPage for both iOS and Android. All the thing set well.see the Below ScreenShot.
in Android this is look way
but in iOS it is not display well
Code :
MasterPage.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="DroidDrawer.MasterPage" Padding="0,0,0,0" Title="Menu" Icon="humburger">
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" Orientation="Vertical" Padding="0,20,0,0" BackgroundColor="#004F80">
<ListView x:Name="listView" VerticalOptions="FillAndExpand" SeparatorVisibility="None" BackgroundColor="#0072BA">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Image Source="{Binding IconSource}" HeightRequest="24" WidthRequest="24" VerticalOptions="Center" Grid.Column="0" Margin="12,10,0,10" />
<Label Text="{Binding Title}" Style="{DynamicResource LabelStyle}" VerticalOptions="Center" HeightRequest="24" TextColor="White" Grid.Column="1" Margin="10,13,0,10" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
MasterPage.xaml.cs
using System;
using System.Collections.Generic;
using Xamarin.Forms;
namespace DroidDrawer
{
public partial class MasterPage : ContentPage
{
public ListView ListView { get { return listView; } }
public MasterPage()
{
InitializeComponent();
var masterPageItem = new List<MasterPageItem>();
masterPageItem.Add(new MasterPageItem
{
Title = "Home",
IconSource = "nav_home.png",
TargetType = typeof(HomePage)
});
masterPageItem.Add(new MasterPageItem
{
Title = "CSS",
IconSource = "nav_appointment.png",
TargetType = typeof(CssPage)
});
masterPageItem.Add(new MasterPageItem
{
Title = "Javascript",
IconSource = "nav_feedback.png",
TargetType = typeof(JavascriptPage)
});
masterPageItem.Add(new MasterPageItem
{
Title = "Html",
IconSource = "nav_financialinfo.png",
TargetType = typeof(HtmlPage)
});
listView.ItemsSource = masterPageItem;
}
}
}
Any Help will be Appreciated.
After 6 hour I got the solution for my problem was the Icon size is too large to it is display so big in the Screen. After setting 30*30 Image size it is solve the problem...

Positon of DropDown list of ComboBox in UWP

I have a ComboBox in my universal application, I want DropDown list open below of my combo not over it.
how can I change position of DropDown list of ComboBox in UWP?
The DropDown of a ComboBox is actually a Popup, and the position where to show this Popup is defined in the code behind, and we can't access to it. One workaround is finding this Popup and relocate it when it is opened, but using this method we need to calculate the VerticalOffset property each time when it is opened, and there are quite many scenarios for different value of VerticalOffset.
So my suggestion is design a custom control which behavior like a ComboBox, for example I created a UserControl like this:
<Button x:Name="rootButton" BorderBrush="Gray" BorderThickness="2" Click="Button_Click" MinWidth="80" Background="Transparent" Padding="0">
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Width="{Binding ElementName=rootButton, Path=ActualWidth}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="32" />
</Grid.ColumnDefinitions>
<TextBlock Text="{x:Bind selectedItem, Mode=OneWay}" Grid.Column="0" VerticalAlignment="Center" FontSize="15" HorizontalAlignment="Center" />
<FontIcon Grid.Column="1" FontSize="12" FontFamily="Segoe MDL2 Assets" Glyph="" HorizontalAlignment="Right"
Margin="0,10,10,10" VerticalAlignment="Center" />
</Grid>
<FlyoutBase.AttachedFlyout>
<MenuFlyout Placement="Bottom" x:Name="menuFlyout">
<MenuFlyoutItem Text="Item 1" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 2" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 3" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 4" Click="MenuFlyoutItem_Click" />
<MenuFlyoutItem Text="Item 5" Click="MenuFlyoutItem_Click" />
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
</Button>
and the code behind in this UserControl:
public sealed partial class CustomComboBox : UserControl, INotifyPropertyChanged
{
public CustomComboBox()
{
this.InitializeComponent();
selectedItem = "";
}
private string _selectedItem;
public string selectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("selectedItem"));
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void MenuFlyoutItem_Click(object sender, RoutedEventArgs e)
{
var item = sender as MenuFlyoutItem;
selectedItem = item.Text;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout(sender as Button);
}
}
And you can use this CustomComboBox in other page like this:
<local:CustomComboBox VerticalAlignment="Center" HorizontalAlignment="Center" />
By default this CustomComboBox will show its DropDown list under it, unless there is no enough space under it to hold this DropDown, in this case, the DropDown will be shown above this CustomComboBox.

How bind DependencyProperty of User Control in HeaderTemplate WinRT XAML?

I have a gridView, and binding my ObservableCollection different class items for my hub page.
Binding different class items to gridView and showing different item Data Templates, Header Templates.
I using User Control in Header Template in gridview.
My headertemplate, including user control and user control include some comboboxes. I want bind in pageRoot datacontext collection to in headertemplate combobox via parameter by on pageRoot object.
I'm create a user control and create some DependencyProperty, combobox eventhandlers.
But can't bind pageRoot DataContext collection to in user control comboboxes :(
My english is poor, sorry for this situation ;)
Thanks for your answers..
My headerdatatemplate:
<DataTemplate x:Key="OrganizationFixtureHeaderTemplate">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}"/>
</StackPanel>
<UserControls:UcCbOrganizationFixtureSelections
Grid.Column="1"
RootElement="pageRoot"
PageOrganizationSource="{Binding PageOrganization, ElementName=pageRoot}"
/>
</Grid>
</DataTemplate>
My user control code:
<UserControl
x:Class="Modern_UI.Common.UserControls.UcCbOrganizationFixtureSelections"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Modern_UI.Common.UserControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="cbOrgFixtureSeasons"
ItemsSource="{Binding Path=DataContext.Seasons, ElementName=RootElement}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
SelectionChanged="CbOrgFixtureSeasons_OnSelectionChanged"
Width="Auto"
Height="Auto"
/>
<ComboBox x:Name="cbOrgFixtureStages"
ItemsSource="{Binding Path=DataContext.FixtureStages, ElementName=RootElement}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
SelectionChanged="CbOrgFixtureStages_OnSelectionChanged"
Width="Auto"
Height="Auto"
/>
<ComboBox x:Name="cbOrgFixtureRounds"
ItemsSource="{Binding Path=DataContext.FixtureRounds, ElementName=RootElement}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
SelectionChanged="CbOrgFixtureRounds_OnSelectionChanged"
Width="Auto"
Height="Auto"
/>
</StackPanel>
</UserControl>
User control code behind:
namespace Modern_UI.Common.UserControls
{
public sealed partial class UcCbOrganizationFixtureSelections : UserControl
{
public DependencyProperty RootElementProperty = DependencyProperty.Register("RootElement",
typeof(string),
typeof(
UcCbOrganizationFixtureSelections
),
null);
public DependencyProperty PageOrganizationSourceProperty = DependencyProperty.Register("PageOrganizationSource",
typeof(Organization),
typeof(
UcCbOrganizationFixtureSelections
),
null);
public string RootElement
{
get { return this.GetValue(RootElementProperty) as string; }
set { this.SetValue(RootElementProperty, value); }
}
public Organization PageOrganizationSource
{
get { return this.GetValue(PageOrganizationSourceProperty) as Organization; }
set { this.SetValue(PageOrganizationSourceProperty, value); }
}
public UcCbOrganizationFixtureSelections()
{
this.InitializeComponent();
}
async private void CbOrgFixtureSeasons_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
//loading root page parameter via "PageOrganizationSource" named DependencyProperty.
}
}
I'm resolved my code problems, and some code added.
1- Bind user control of root page DataContext. Because user control inside gridview template. If insided a control in datatemplate, binding default datacontext of datatemplate itemsources. I want don't related with itemsource datacontext, bind rootpage datacontext.
Replaced Codes, in DataTemplate:
<DataTemplate x:Key="OrganizationFixtureHeaderTemplate">
<Grid Margin="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="{Binding Title}" Style="{StaticResource TitleTextStyle}"/>
</StackPanel>
<UserControls:UcCbOrganizationFixtureSelections
Grid.Column="1"
RootElement="pageRoot"
DataContext="{Binding DataContext, ElementName=pageRoot}"
PageOrganizationSource="{Binding PageOrganization, ElementName=pageRoot}"
/>
</Grid>
</DataTemplate>
2- I'm replace in user control xaml code. User Control's Datacontext is of rootPage DataContext now. I'm can be binding every collection to my comboboxes this situation.
Replaced codes:
<UserControl
x:Class="Lig_TV_Modern_UI.Common.UserControls.UcCbOrganizationFixtureSelections"
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">
<StackPanel Orientation="Horizontal">
<ComboBox x:Name="cbOrgFixtureSeasons"
ItemsSource="{Binding Seasons}"
SelectedValuePath="Id"
DisplayMemberPath="Name"
SelectionChanged="CbOrgFixtureSeasons_OnSelectionChanged"
Width="Auto"
Height="Auto"
/>
</StackPanel>
</UserControl>
Thanks for thinking on this problem. This structure can be communicated every element, and can be binding every collection without datatemplate itemsource datacontext. If use a datatemplate and need eventhandlers of controls, can be use User control.
Good coded days ;)

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}">

Resources