Xamarin Binding property not found - c#

I have collection view defined like this:
<RefreshView
Command="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}">
<CollectionView
ItemsSource="{Binding Menus}">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="128" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image
Source="{Binding ImageURI}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Aspect="AspectFill"
Opacity="0.64"
Grid.RowSpan="2"
Grid.ColumnSpan="3"/>
<Label
Text="{Binding Name}"
FontAttributes="Bold"
FontSize="Large"
TextColor="Black"
Grid.Row="0"
Grid.ColumnSpan="3"/>
<Label
Text="{Binding Description}"
FontSize="Body"
TextColor="Black"
Grid.Row="1"
Grid.ColumnSpan="3"/>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</RefreshView>
But when built, nothing comes up in the view and the console show the following errros:
[0:] Binding: 'ImageURI' property not found on '<model>', target property: 'Xamarin.Forms.Image.Source'
[0:] Binding: 'Name' property not found on '<model>', target property: 'Xamarin.Forms.Label.Text'
[0:] Binding: 'Description' property not found on '<model>', target property: 'Xamarin.Forms.Label.Text'
When I change the view to this:
<Label Text="{Binding Menus.Count}"
TextColor="Black"/>
<Label Text="{Binding Menus[0]}"
TextColor="Black"/>
<Label Text="{Binding Menus[0].Name}"
TextColor="Black"/>
The result looks like this, but still produces the same error message.
[0:] Binding: 'Name' property not found on 'hollywood.Models.MenuHandle', target property: 'Xamarin.Forms.Label.Text'
The view model and model respectively look like this:
public class MenuListViewModel : BaseViewModel
{
public MenuListViewModel()
{
//RefreshMenus();
Menus.Add(new MenuHandle { Name = "Test", Description="test2"});
Title = "Menu";
}
public async Task RefreshMenus()
{
IsRefreshing = true;
TimeSpan age = DateTime.Now - MenusAge;
if (age.TotalSeconds > 1)
{
try
{
Menus = await App.ApiConnection.GetMenusAsync();
MenusAge = DateTime.Now;
}
catch { }
}
IsRefreshing = false;
}
ObservableCollection<MenuHandle> menus = new ObservableCollection<MenuHandle>();
public ObservableCollection<MenuHandle> Menus
{
get { return menus; }
private set { SetProperty(ref menus, value); }
}
bool isRefreshing;
public bool IsRefreshing
{
get { return isRefreshing; }
private set { SetProperty(ref isRefreshing, value); }
}
DateTime MenusAge = DateTime.MinValue;
public ICommand RefreshCommand => new Command(async () => await RefreshMenus());
}
}
Model class:
public class MenuHandle
{
[JsonProperty("name")]
public string Name;
[JsonProperty("url_name")]
public string URLName;
[JsonProperty("description")]
public string Description;
[JsonProperty("image")]
public Uri ImageURI;
}
Any suggestions would be greatly appreciated.

You need to declare your variables as properties because bindings works with properties:
public class MenuHandle
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("url_name")]
public string URLName { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("image")]
public Uri ImageURI { get; set; }
}

Related

Changing Data in CollectionView (Xamarin)

I use CollectionView to show data on screen, but when I change data, UI is not changing, although I am using OnPropertyChanged. Here is the code:
Xaml
<CollectionView ItemsSource="{Binding GridData}" Margin="15">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Margin="15" Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0"
Grid.Column="0"
HorizontalTextAlignment="Start"
Text="{Binding Title}"
FontSize="Small"/>
<Label Grid.Row="0"
Grid.Column="1"
HorizontalTextAlignment="End"
Text="{Binding Data}"
TextColor="Black"
FontSize="Medium">
<Label.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding Source={x:Reference Page} , Path=BindingContext.TapCommand}"
CommandParameter="{Binding Title}" />
</Label.GestureRecognizers>
</Label>
<BoxView Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
BackgroundColor="LightGray"
CornerRadius="2"
HorizontalOptions="FillAndExpand"
HeightRequest="1"></BoxView>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
ViewModel
private List<CollectionEntity> _gridData;
public List<CollectionEntity> GridData
{
get => _gridData;
set
{
if (_gridData != value)
{
_gridData = value;
OnPropertyChanged(nameof(GridData));
}
}
}
public ICommand TapCommand
{
get
{
return new Command<CollectionView>((commandParameters) =>
{
OpenEditing(commandParameters.ToString());
OnPropertyChanged(nameof(GridData));
});
}
}
Model (is in the same file, as is ViewModel)
public class CollectionEntity: INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string Title { get; set; }
public string Data { get; set; }
}
So, when I tap on the Label, UI does not react. I tried to write it according to this answer, but cannot understand, what is incorrect.
UPD: new command
public ICommand TapCommand => new Command<object>((commandParameters) =>
{
OpenEditing(commandParameters.ToString()); // changing data
});
Though you had write the code about INotifyPropertyChanged in your model but you didn't implement it on the property Title and Data . Modify the code like following
private string title;
public string Title
{
get => title;
set
{
if (title!= value)
{
title = value;
OnPropertyChanged(nameof(Title));
}
}
}
private string data;
public string Data
{
get => data;
set
{
if (data!= value)
{
data= value;
OnPropertyChanged(nameof(Data));
}
}
}
In addition, the code in TapCommand seems will not change the value of source . You could binding the whole model to the command and set the title or data in command as you want .
CommandParameter="{Binding .}"
public ICommand TapCommand
{
get
{
return new Command<CollectionView>((arg) =>
{
var model = arg as CollectionEntity;
// model.Title = "xxx";
});
}
}

Get list of CollectionView return Object and put in IIList of Model in xamarin.form

In Xamarin,Try to get list of items in collectionView
My Model is
public class DrugModel
{
public string Name { get; set; }
public bool IsUsed { get; set; }
public int NumberUsed { get; set; }
}
] bind CillectionView to List that returview Api, and when debugger arrive to my change event cant get data and put on my List
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class DrugMissionPage : ContentPage
{
public IList<DrugModel> SelectedDrug;
public DrugMissionPage()
{
InitializeComponent();
}
private void listDrug_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var selectedDrugList =e.CurrentSelection ;
var tyy = selectedDrugList.ToList() as IList<DrugModel>;
foreach (var item in selectedDrugList)
{
SelectedDrug.Add(item);
}
}
And this is my View
<CollectionView
x:Name="listDrug"
VerticalOptions="StartAndExpand"
SelectionMode="Multiple"
ItemsLayout="VerticalList" SelectionChanged="listDrug_SelectionChanged">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Frame Padding="10">
<Frame BackgroundColor="AliceBlue" HasShadow="True" CornerRadius="10" Padding="10" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding Name}" FontSize="Default" HorizontalOptions="StartAndExpand" Grid.Row="0" Grid.Column="0" Margin="0,10,10,0"></Label>
</StackLayout>
</Frame>
</Frame>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
}
How can I fill
public IList<DrugModel> SelectedDrug;
When debugger pass from
var tyy = selectedDrugList.ToList() as IList<DrugModel>;
foreach (var item in selectedDrugList)
{
SelectedDrug.Add(item);
}
"tyy" will be null
You could use the Cast<class> to convert List to List.
Change:
var tyy = selectedDrugList.ToList() as IList<DrugModel>;
To:
var tyy = selectedDrugList.Cast<DrugModel>();

Binding individual property based of sqlite local database

I have created a ListView with items based on data saved in database. Its computer list with few properties as name, ipAdress, port and selected. If selected = true computer is marked as default and I need to change his appearance in ListView.
I need to create a binding to property which isnt part of the table.
I have simple list of computers (XAML)
<ListView x:Name="CompListView" HasUnevenRows="true" Grid.Row="1" SeparatorColor="Black" ItemsSource="{Binding ComputerList}"
SelectedItem="{Binding SelectedComputerItem, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding ComputerName}" Grid.Row="1" Font="20" TextColor="{Binding Selected_Color}" />
<Label Text="{Binding IPAddress}" Grid.Row="0" Font="20" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="{Binding Selected_Color}"/>
<Label Text="{Binding Port}" Grid.Row="1" Font="13" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="{Binding Selected_Color}"/>
<Image Source="computerpng.png" Grid.Row="0" Grid.Column="0" WidthRequest = "24" HeightRequest = "24" HorizontalOptions = "Start"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Base computer View connected to database.
public class BaseComputerView : INotifyPropertyChanged
{
public Computer _computer;
public INavigation _navigation;
public IComputer _computerRepository;
public string ComputerName
{
get => _computer.ComputerName;
set
{
_computer.ComputerName = value;
NotifyPropertyChanged("Computer_Name");
}
}
public string IPAddress
{
get => _computer.IPAddress;
set
{
_computer.IPAddress = value;
NotifyPropertyChanged("IPAddress");
}
}
public string Port
{
get => _computer.Port;
set
{
_computer.Port = value;
NotifyPropertyChanged("Port");
}
}
public bool Selected
{
get => _computer.Selected;
set
{
_computer.Selected = value;
NotifyPropertyChanged("Selected");
}
}
Based on _Selected I added property "Selected_Color" within the same class. Goal is to change back color of controls if the item is selected.
public string Selected_Color
{
get
{
string Text_Color = string.Empty;
try
{
if (Selected == true)
{
Text_Color = "#33cc33";
}
else
{
Text_Color = "#000000";
}
}
catch (Exception ex)
{
return "#000000";
}
return Text_Color;
}
}
This code however looks up for property "Selected_Color" in Computer table, which is wrong.
use the Ignore attribute to tell SQLite to ignore your new property
[Ignore]
public string Selected_Color
alternately, you could use a ValueConverter to set the color based on the Selected property
Thanks for your answer,
I figured it out by adding Selected_Color as Computer Table property.
[Table("Computer")]
public class Computer
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string ComputerName { get; set; }
public string IPAddress { get; set; }
public string Port { get; set; }
public bool Selected { get; set; }
[Ignore]
public string Selected_Color
{
get
{
string Text_Color = string.Empty;
try
{
if (Selected == true)
{
//Green color
Text_Color = "#33cc33";
}
else
{
Text_Color = "#000000";
}
}
catch (Exception ex)
{
return "#000000";
}
return Text_Color;
}
}
}
App_ComputerList_Image
Works fine until I open one of the computers for edit and come back to computer list. What is weird is fact that I get Java exception not for the first time I do that but only for the second time. So I am able to open one of the items and came back to computer list. If I repeat that then I get this Java exception.
just wanted to add answer for everyone who would fight with similar problem, that I found a better way to do this. You can define data templates based on your property and then use it to draw your Listview like this. Difference in this case is textcolor of the labels.
<ResourceDictionary>
<DataTemplate x:Key="SelectedComputer">
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding ComputerName}" Grid.Row="1" Font="20" TextColor="Green" />
<Label Text="{Binding IPAddress}" Grid.Row="0" Font="20" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="Green"/>
<Label Text="{Binding Port}" Grid.Row="1" Font="13" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="Green"/>
<Image Source="computerpng.png" Grid.Row="0" Grid.Column="0" WidthRequest = "24" HeightRequest = "24" HorizontalOptions = "Start"/>
</Grid>
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="Computer">
<ViewCell>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding ComputerName}" Grid.Row="1" Font="20" TextColor="Black" />
<Label Text="{Binding IPAddress}" Grid.Row="0" Font="20" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="Black"/>
<Label Text="{Binding Port}" Grid.Row="1" Font="13" Grid.Column="1" HorizontalOptions="EndAndExpand" HorizontalTextAlignment="End" TextColor="Black"/>
<Image Source="computerpng.png" Grid.Row="0" Grid.Column="0" WidthRequest = "24" HeightRequest = "24" HorizontalOptions = "Start"/>
</Grid>
</ViewCell>
</DataTemplate>
<local:ComputerTemplateSelector x:Key="ComputerTemplateSelector" SelectedComputer="{StaticResource SelectedComputer}" Computer="{StaticResource Computer}" />
</ResourceDictionary>
Template selector:
public class ComputerTemplateSelector : DataTemplateSelector
{
public DataTemplate SelectedComputer { get; set; }
public DataTemplate Computer { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
return ((SQLite_Database.Computer)item).Selected == true ? SelectedComputer : Computer;
}
}

Xamarin local variable in xaml.cs and printing through the XAML file

I want to be able to print properties from 'CurrentOrder' in the XAML.
Here is what I have so far:
// OrderPage.xaml.cs
public partial class OrderPage : ContentPage
{
private Order _currentOrder;
public Order CurrentOrder
{
get { return _currentOrder; }
}
public OrderPage()
{
InitializeComponent();
_currentOrder = Order.DefaultOrder;
addPin("Start", _currentOrder.PickupAddress.Latitude, _currentOrder.PickupAddress.Longitude);
addPin("End", _currentOrder.DropoffAddress.Latitude, _currentOrder.DropoffAddress.Longitude);
this.BindingContext = this;
}
public OrderPage(Order order)
{
InitializeComponent();
_currentOrder = order;
addPin("Start", _currentOrder.PickupAddress.Latitude, _currentOrder.PickupAddress.Longitude);
addPin("End", _currentOrder.DropoffAddress.Latitude, _currentOrder.DropoffAddress.Longitude);
Debug.WriteLine(_currentOrder.ToString());
this.BindingContext = this;
}
}
Here is the Order class, which has several properties with other classes.
public class Order : INotifyPropertyChanged
{
public static Order DefaultOrder
{
// I have a default order return here, but in the sake of privacy, I'm removing my test addresses
}
// event to handle changes in the order status
public event PropertyChangedEventHandler PropertyChanged;
public enum Status { Preview, NeedsDriver, WaitingDriver, InTransit, NeedsSignature, Complete, Refunded }
public string ID { get; set; }
public string Description { get; set; }
private Status _orderStatus;
public Status OrderStatus {
get
{
return _orderStatus;
}
set
{
_orderStatus = value;
// tell the view that the order status has changed
OnPropertyChanged("OrderStatus");
}
}
public Contact PickupContact { get; set; }
public Contact DropoffContact { get; set; }
public Address PickupAddress { get; set; }
public Address DropoffAddress { get; set; }
public DateTime PickupTime { get; set; }
public DateTime DropoffTime { get; set; }
// Formatted Pickup and Dropoff Times
public string PickupTimeFormatted
{
get { return PickupTime.ToString("g"); }
}
public string DropoffTimeFormatted
{
get { return DropoffTime.ToString("g"); }
}
public Order()
{
}
// Handler to tell the view that the order status has changed
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public override string ToString()
{
return string.Format("[Order: ID={0}, Description={1}, OrderStatus={2}, PickupContact={3}, DropoffContact={4}, PickupAddress={5}, DropoffAddress={6}, PickupTime={7}, DropoffTime={8}, PickupTimeFormatted={9}, DropoffTimeFormatted={10}]", ID, Description, OrderStatus, PickupContact, DropoffContact, PickupAddress, DropoffAddress, PickupTime, DropoffTime, PickupTimeFormatted, DropoffTimeFormatted);
}
}
Finally, the 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"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
x:Class="Divco.OrderPage"
Title="Order">
<ContentPage.BindingContext>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout Spacing="10" x:Name="layout" VerticalOptions="FillAndExpand">
<StackLayout>
<maps:Map WidthRequest="320"
HeightRequest="150"
x:Name="MyMap"
IsShowingUser="false"
MapType="Street" />
</StackLayout>
<StackLayout Padding="20, 20, 20, 0">
<!--<Label Content="{Binding ID, Source={StaticResource CurrentOrder}}"></Label>-->
<Label Text="{Binding ID}"
TextColor="Fuchsia" />
<Label Text="Description"
LineBreakMode="WordWrap" />
</StackLayout>
<StackLayout Padding="20, 20, 20, 0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Pickup"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
TextColor="Fuchsia"/>
<Label Text="Top Left"
Grid.Row="1"
Grid.Column="0" />
<Label Text="Top Right"
Grid.Row="1"
Grid.Column="1" />
<Label Text="Dropoff"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="2"
TextColor="Fuchsia"/>
<Label Text="Bottom Left"
Grid.Row="3"
Grid.Column="0" />
<Label Text="Bottom Right"
Grid.Row="3"
Grid.Column="1" />
</Grid>
</StackLayout>
<StackLayout Padding="20, 20, 20, 20" VerticalOptions="EndAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Text="Call X"
BackgroundColor="Fuschia"
TextColor="White"
Grid.Row="0"
Grid.Column="0"/>
<Button Text="Navigate!"
BackgroundColor="Fuschia"
TextColor="White"
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"/>
</Grid>
</StackLayout>
</StackLayout>
</ContentPage.Content>
You can see where I attempted to print the ID of the order in the XAML. All of the supporting classes for the Order have ToString(s) which return the needed information for the order page, so I'm not really worried about printing '_currentOrder.PickupAddress.Address1', for example.
your BindingContext is a reference to the current Page
this.BindingContext = this;
so your binding path would look like:
<Label Text="{Binding CurrentOrder.ID}" TextColor="Fuchsia" />

Having problems binding my datagrid to data from my database

i've a problem to use datagrid in wpf mvvm project
Here is my xaml :
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
x:Class="noteManager.MainWindow"
xmlns:vm="clr-namespace:noteManager.ViewModel"
DataContext="{StaticResource noteManagerViewModel}"
Title="NoteManager" Height="490" Width="525">
<Grid Margin="0,0,0,-132.5">
<Grid.RowDefinitions>
<RowDefinition Height="10"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="200"></RowDefinition>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="110"></RowDefinition>
<RowDefinition Height="111"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="80"></ColumnDefinition>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Login :" FontSize="16" Grid.Column="2" Margin="51,9,50,0" Grid.RowSpan="2" Height="23" VerticalAlignment="Top" Grid.ColumnSpan="2"/>
<TextBox Text="{Binding Login}" Grid.Row="1" Grid.Column="3" Margin="14,0,86,29" Grid.ColumnSpan="2"/>
<Button Background="LightGreen" Foreground="Green" Command="{Binding testConnexion}" x:Name="testConnexion" Content="Connexion" Grid.Row="1" Grid.Column="2" Margin="51,29,86,0" Grid.ColumnSpan="3"/>
<Button Command="{Binding addUser}" Content="+" Grid.Row="1" Grid.Column="4" Margin="34,1,20,0" RenderTransformOrigin="0.742,0.468"/>
<DataGrid Name="dataGrid1" Grid.Row="2" Margin="8,7,-22,7" AutoGenerateColumns="False"
ItemsSource="{Binding _DataGridNotes}" SelectedItem="{Binding Path=MySelectedNote}" HorizontalAlignment="Center"
Width="480" Grid.ColumnSpan="6" Grid.Column="1">
<DataGrid.Columns>
<DataGridTextColumn Width="100" Binding="{Binding Path=NoteTitle}" Header="Titre" />
<DataGridTextColumn Width="200" Binding="{Binding Path=NoteContent}" Header="Note" />
<DataGridTextColumn Width="100" Binding="{Binding Path=NoteCreatedAt}" Header="Date de création" />
<DataGridTextColumn Width="100" Binding="{Binding Path=NoteUpdatedAt}" Header="Dat MAJ" />
</DataGrid.Columns>
</DataGrid>
<TextBlock Text="Titre" FontSize="16" Grid.Row="3" Grid.Column="1" Margin="27,8,7,1"/>
<TextBox Text="{Binding Path=titre, Mode=TwoWay}" Grid.Row="3" Grid.Column="2" Margin="17,10,23,10" Grid.ColumnSpan="5"/>
<TextBlock Text="Note" FontSize="16" Grid.Row="4" Grid.Column="1" Margin="27,4,7,0"/>
<TextBox Text="{Binding Path=description, Mode=TwoWay}" Grid.Row="4" Grid.Column="2" Margin="17,10,23,8" Grid.ColumnSpan="5"/>
<Button Command="{Binding Path=DeleteNote}" Background="LightPink" Foreground="red" Content="Supprimer" Grid.Row="5" Grid.Column="1" Margin="55,7,26,81" Grid.ColumnSpan="2"/>
<Button Command="{Binding Path=UpdateANote}" Content="Mettre à jour" Grid.Row="5" Grid.Column="3" Margin="14,7,67,81" Grid.ColumnSpan="2" RenderTransformOrigin="0.5,0.5"/>
<Button Command="{Binding Path=AddNote}" Content="Ajouter" Grid.Row="5" Grid.Column="4" Margin="78,7,10,81" Grid.ColumnSpan="3"/>
</Grid>
</Window>
Here is my viewModel :
namespace noteManager.ViewModel
{
public class noteManagerViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void Notify(string property)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
string login;
int currentUser;
public string Login
{
get
{
return login;
}
set
{
login = value; Notify("Login");
}
}
private bool _canExecute;
public noteManagerViewModel()
{
_canExecute = true;
}
private ICommand _testConnexion;
public ICommand testConnexion
{
get
{
return _testConnexion ?? (_testConnexion = new CommandHandler(() => Connexion(), _canExecute));
}
}
private ICommand _addUser;
public ICommand addUser
{
get
{
return _addUser ?? (_addUser = new CommandHandler(() => AjoutUser(), _canExecute));
}
}
private ObservableCollection<DataGridNotes> _DataGridNotes = new ObservableCollection<DataGridNotes>();
public ObservableCollection<DataGridNotes> dataGridNotes
{
// No need for a public setter
get { return _DataGridNotes; }
}
}
the other class that i use :
public class User
{
/*public User()
{
this.Note = new HashSet<Note>();
}*/
public int Id { get; set; }
public string Login { get; set; }
//public virtual ICollection<Note> Note { get; set; }
}
public class Note : INotifyPropertyChanged
{
public int Id { get; set; }
public string NoteText { get; set; }
public string ContentText { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public int UserId { get; set; }
//public virtual User User { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public void Notify(string property)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
public class DataGridNotes
{
private string _noteTitle;
private string _noteContent;
private string _noteCreatedAt;
private string _noteUpdatedAt;
public string NoteTitle { get { return _noteTitle; } set { _noteTitle = value; } }
public string NoteContent { get { return _noteContent; } set { _noteContent = value; } }
public string NoteCreatedAt { get { return _noteCreatedAt; } set { _noteCreatedAt = value; } }
public string NoteUpdatedAt { get { return _noteUpdatedAt; } set { _noteUpdatedAt = value; } }
}
sorry for the ugly code, new to c# for a project.
i want to use the datagrid in my viewmodel but don't find a way to make it work (would like to write data from mysql database in the datagrid
Have you an idea to make it work ?
thx in advance
Ok, It's tough to spot what you are doing wrong without seeing the ViewModel, however you may want to check the following:
1) The DataContext is correct.
2) The property _DataGridNotes exists. Check the program output to make sure that there are no warnings informing you that bindings are broken.
The property you are looking to have should look something like this:
List<Note> _DataGridNotes
{
get
{
// get notes from SQL request
// construct list of Note and return list
}
}
You should also make sure that the Note class contains the properties required (NoteTitle, NoteContent, NoteCreatedAt, NoteUpdatedAt).
It might also be worth passing back some dummy notes to debug if the problem lies in the request to the SQL database.
The problem is that you are trying to bind to a private Observable collection _DataGridNotes where you should be binding to the property dataGridNotes:
ItemsSource="{Binding dataGridNotes}"

Categories