Checkbox Event not trigerred in Listview UWP - c#

I'm actually developping an UWP app who's reading Excel data, and display it on a form. Every Excel sheet are represented with RadioButton, and when the user click on a RadioButton, I update a ListView with the corresponding data.
Every item of the ListView have different data, and 2 checkboxes. This checkboxes can have the state "true" or "false", and if the user need to change the state, I want to modify his value
But the problem is, there is no event triggered with all the checkboxes when I check them. I tried to search and try to make my own template, but without success.
All the data are stored in a class :
public class REFERENCES
{
public int AI_ID { get; set; }
public int ID_poste { get; set; }
public string reference { get; set; }
public string designation { get; set; }
public bool avance { get; set; }
public bool jour { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public REFERENCES(int ai_id, int id_poste, string ref_, string des_, string avance_, string jour_)
{
AI_ID = ai_id;
ID_poste = id_poste;
reference = ref_;
designation = des_;
if(jour_ != null)
{
jour = true;
}
else
{
jour = false;
}
if (avance_ != null)
{
avance = true;
}
else
{
avance = false;
}
}
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
And this is my ListView :
<ListView x:Name="ListViewData" SelectionMode="None" HorizontalAlignment="Center" Height="412" VerticalAlignment="Top" Width="650" Margin="0,218,0,0" >
<ListView.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Height="35" Margin="0,0,0,0" VerticalAlignment="Center" >
<TextBlock Text="AI_ID" Width="0" Visibility="Collapsed" />
<TextBlock Text="Désignations" FontSize="20" Width="300" Foreground="Blue" TextAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Références" FontSize="20" Width="150" Foreground="Blue" TextAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Avance" FontSize="20" Width="100" Foreground="Blue" TextAlignment="Center" VerticalAlignment="Center" />
<TextBlock Text="Jour" FontSize="20" Width="100" Foreground="Blue" TextAlignment="Center" VerticalAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListView.HeaderTemplate>
<ListView.ItemTemplate>
<DataTemplate x:DataType="ExcelLinkData:REFERENCES">
<StackPanel Orientation="Horizontal" >
<TextBlock Name="ItemAI_ID" Text="{x:Bind AI_ID}" Width="0" />
<TextBlock Name="ItemDesignation" Text="{x:Bind designation}" Width="300" FontSize="16" Height="55" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center"/>
<TextBlock Name="ItemReference" Text="{x:Bind reference}" Width="150" FontSize="16" Height="55" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Center" />
<Grid Width="100" Height="55" VerticalAlignment="Center" HorizontalAlignment="Center">
<CheckBox Name="ItemAvance" IsChecked="{x:Bind avance}" Tag="{x:Bind AI_ID}" Checked="CHANGE_STATUS_REFERENCE"/>
</Grid>
<Grid Width="100" Height="55" VerticalAlignment="Center" HorizontalAlignment="Center">
<CheckBox Name="ItemJour" IsChecked="{x:Bind jour}" Tag="{x:Bind AI_ID}" Checked="CHANGE_STATUS_REFERENCE"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The method "CHANGE_STATUS_REFERENCE" is the method where I want to change the state in my class.
I tried different solutions, but I'm not an expert in UWP, so if anyone got an advice, I'll take it !
Thanks in advance for your time !
Guillaume

In UWP, default mode for Binding is OneTime. And when you change property from viewmodel then no event is triggered. By changing Binding to OneWay / TwoWay (depending on your usage), viewmodel will trigger the event.
Change
IsChecked="{x:Bind jour}"
To
IsChecked="{x:Bind jour Mode=TwoWay}"

Change
<CheckBox Name="ItemAvance" IsChecked="{x:Bind avance}" Tag="{x:Bind AI_ID}" Checked="CHANGE_STATUS_REFERENCE"/>
to
<CheckBox Name="ItemAvance" IsChecked="{x:Bind avance}" Tag="{x:Bind AI_ID}" Command="{Binding CHANGE_STATUS_REFERENCE}"/>
Add a "Flip Function" to your class:
private void Flip()
{
this.avance = !this.avance;
}
Set up a RelayCommand:
RelayCommand _flipCommand = new RelayCommand(this.Flip);
and Implement CHANGE_STATUS_REFERENCE as an ICommand like so:
public ICommand CHANGE_STATUS_REFERENCE
{
get
{
return _flipCommand;
}
}

Related

How to check to state of controls created dynamically using itemscontrol after naming them in the itemscontrol wpf C#

For my code, I've created multiple control of the same type (i.e. Checkbox) using itemscontrol bound to a class "MyClass". I've named the checkbox control as "checkControl". Now, as I've multiple checkbox control created in the UI, I want to check their state and differentiate among them. How should I proceed? I'm thinking of using findvisualchild & findvisualparent? But, I don't have any idea how to use it?
<ItemsControl Name="myList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="30,80,10,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Border x:Name="tempBorder" BorderBrush="LightGray" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4" Margin="0,-30,-60,-30"
Background="LightGray">
<StackPanel Orientation="Horizontal" Background="Transparent" Margin="0">
<StackPanel Background="White" Orientation="Horizontal">
<CheckBox x:Name="checkControl" Margin="7,7,0,0" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked">
<WrapPanel>
<Image Source="/Images/myimage.png" Margin="0,10,0,0"></Image>
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<TextBlock Text="{Binding Disk}" FontFamily="roboto" FontSize="14"/>
<Rectangle Width="340" Height="1" Margin="0,5,5,5" Fill="Black"/>
<TextBlock>
<Run Text="Item:" FontFamily="roboto" FontSize="14"/>
<Run Text="{Binding Path=Name, StringFormat=' {0} Jr.'}" FontSize="20" Foreground="Orange"
FontWeight="DemiBold"/>
</TextBlock>
</StackPanel>
</WrapPanel>
</CheckBox>
</StackPanel>
<StackPanel Orientation="Vertical" Background="LightGray" Margin="0" HorizontalAlignment="Center" Width="765"
VerticalAlignment="Center">
<TextBlock Text="Select the Option:" Margin="15,7,0,7" FontFamily="roboto"/>
<ComboBox x:Name="comboControl" Margin="15,5,0,7" Width="750" SelectionChanged="comboControl_SelectionChanged"/>
</StackPanel>
</StackPanel>
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
For My Backend C# Code:
Class
public class MyClass
{
public string Disk { get; set; }
public string Name { get; set; }
public MyClass()
{
}
public MyClass(string album, string name)
{
this.Disk = album;
this.Name = name;
}
}
In my Xaml.cs
public ObservableCollection<MyClass> StudentDisk { get; set; }
//somecode
StudentDisk.Add(new MyClass("Disk 4 ", "John")); //For populating
//somecode
myList.ItemsSource = StudentDisk;
it is possible to differentiate checkBoxes by their DataContext, which should be unique:
void CheckBox_Checked(object sender, RoutedEventArgs e)
{
var checkbox = (CheckBox)sender;
var item = (MyClass)checkbox.DataContext;
MessageBox.Show(item.Disk + " " + item.Name);
}

display grid item position number in a grid observable collection

Below is my item template in a grid view.
</Grid.ColumnDefinitions>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SerialNumber}" VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" Margin="10" FontSize="25"/>
<TextBlock Text="." VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" FontSize="25" />
</StackPanel>
<Image Grid.Column="0" Margin="20" Height="100" Width="150" HorizontalAlignment="Center" Source="{Binding ImageUri,Mode=TwoWay}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
what i am trying to achieve is to display the item position in the collection in the TextBlock Text="{Binding SerialNumber} (if this were to be a list view, it would be row number), please how do i achieve this.
You just need to define a class with the specific properties and bind it on xaml.
I made a simple code sample for your reference:
<GridView ItemsSource="{Binding oc}">
<GridView.ItemTemplate>
<DataTemplate>
<Border>
<StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SerialNumber}" VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" Margin="10" FontSize="25"/>
<TextBlock Text="." VerticalAlignment="Center" HorizontalAlignment="Left" FontWeight="Bold" FontSize="25" />
</StackPanel>
<Image Grid.Column="0" Margin="20" Height="100" Width="150" HorizontalAlignment="Center" Source="{Binding source,Mode=TwoWay}" VerticalAlignment="Center"/>
</StackPanel>
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
public sealed partial class MainPage : Page
{
public ObservableCollection<Test> oc { get; set;}
public MainPage()
{
this.InitializeComponent();
oc = new ObservableCollection<Test>();
oc.CollectionChanged += Oc_CollectionChanged;
for (int i=0;i<10;i++)
{
oc.Add(new Test() {SerialNumber=i,source=new BitmapImage(new Uri("ms-appx:///Assets/test.png")) });
}
this.DataContext = this;
}
private void Oc_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
for (int i =e.OldStartingIndex; i<oc.Count;i++)
{
oc[i].SerialNumber = i;
}
}
}
}
public class Test:INotifyPropertyChanged
{
private int _SerialNumber;
public int SerialNumber
{
get { return _SerialNumber; }
set
{
_SerialNumber = value;
RaisePropertyChanged("SerialNumber");
}
}
private BitmapImage _source;
public BitmapImage source
{
get { return _source; }
set
{
_source = value;
RaisePropertyChanged("source");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string PropertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,new PropertyChangedEventArgs(PropertyName));
}
}
}

C# ListBox, different background for each item

I have ListBox in xaml:
<ListBox Name="feedListBox" Height="758" HorizontalAlignment="Center" Margin="0,10,0,0" VerticalAlignment="Top" Width="480" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Background="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Top" Width="480">
<TextBlock FontWeight="Bold" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="#FF000000" Text="{Binding Title.Text, Converter={StaticResource RssTextTrimmer}}" />
<TextBlock Name="feedSummary" Foreground="#FF000000" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary.Text, Converter={StaticResource RssTextTrimmer}}" />
<TextBlock Name="feedPubDate" Foreground="#FF939393" Margin="12,0,10,10" Text="{Binding PublishDate.DateTime}" HorizontalAlignment="Right" />
<Border BorderThickness="1" Height="2" HorizontalAlignment="Center" VerticalAlignment="Top" Width="480" BorderBrush="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
How can I specify different background for each item?
add a Brush property to your viewmodel and bind the controls in your DataTemplate to it
ViewModel:
using System.ComponentModel;
using System.Windows.Media;
...
public class YourViewModel : INotifyPropertyChanged{
...
private Brush _backgroundCol = Brushes.Red; //Default color
public Brush BackgroundCol
{
get { return _backgroundCol; }
set
{
_backgroundCol = value;
OnPropertyChanged("BackgroundCol");
}
}
...
}
xaml:
<TextBlock Name="feedPubDate" Background="{Binding Path=BackgroundCol}" />
for Information about how to implement the INotifyPropertyChanged interface have a look at: Implementing INotifyPropertyChanged - does a better way exist?
Try this:
XAML:
<ListBox Name="feedListBox" Height="758" HorizontalAlignment="Center" Margin="0,10,0,0" VerticalAlignment="Top" Width="480" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectionChanged="feedListBox_SelectionChanged" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="1" Background="White">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Top" Width="480">
<Grid Background="{Binding feedTitleBack}">
<TextBlock FontWeight="Bold" FontSize="24" Name="feedTitle" TextWrapping="Wrap" Margin="12,0,0,0" HorizontalAlignment="Left" Foreground="#FF000000" Text="{Binding Title}"/>
</Grid>
<Grid Background="{Binding feedSummaryBack}">
<TextBlock Name="feedSummary" Foreground="#FF000000" TextWrapping="Wrap" Margin="12,0,0,0" Text="{Binding Summary}" />
</Grid>
<Grid Background="{Binding feedPubDateBack}">
<TextBlock Name="feedPubDate" Foreground="#FF939393" Margin="12,0,10,10" Text="{Binding PublishDate}" HorizontalAlignment="Right" />
</Grid>
<Border BorderThickness="1" Height="2" HorizontalAlignment="Center" VerticalAlignment="Top" Width="480" BorderBrush="Black" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
CS:
public class data
{
public string Title { get; set; }
public string feedTitleBack { get; set; }
public string Summary { get; set; }
public string feedSummaryBack { get; set; }
public string PublishDate { get; set; }
public string feedPubDateBack { get; set; }
public data() { }
public data(string Title, string feedTitleBack, string Summary, string feedSummaryBack, string PublishDate, string feedPubDateBack)
{
this.Title = Title;
this.feedTitleBack = feedTitleBack;
this.Summary = Summary;
this.feedSummaryBack = feedSummaryBack;
this.PublishDate = PublishDate;
this.feedPubDateBack = feedPubDateBack;
}
}
void loadData()
{
List<data> obj = new List<data>();
obj.Add(new data("Title1", "Red", "Summary1", "Green", "Date", "Blue"));
obj.Add(new data("Title1", "#DD4B39", "Summary1", "#006621", "Date", "#1A0DAB"));
feedListBox.ItemsSource = obj;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
loadData();
}

Binding Error in my windows phone 8 project

Well I am trying to do a simple binding in a Long list but the emulator is throwing a debug Exception in
private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
I would paste my code below
My model class is
public class CommentView
{
public string ID { get; set; }
public string IsApproved { get; set; }
public string PostersComment { get; set; }
public string Name { get; set; } //Note that this is the name of the Jizuser
public string PostedDate { get; set; }
public string PostedTime { get; set; }
}
I am doing my binding from the xaml csharp code. so the script is pasted below
List<CommentView> commenterContainer = new List<CommentView>();
commenterContainer.Add(new CommentView() { Name ="FEMI", IsApproved="True", ID="1", PostedDate="2/3/2014", PostedTime="01:02:2011", PostersComment= "Me" });
commenterlist.ItemsSource = commenterContainer;
This is the longlist item. how I crafted the dataItem template
<phone:LongListSelector Margin="3" x:Name="commenterlist" SelectionChanged ="Bloglist_SelectionChanged" Grid.Row="6"
Background="White">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="#4063A9">
<StackPanel Margin="10,10,10,10" Orientation="Vertical" >
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="{Binding ID}" Visibility="Collapsed"/>
<Image Source="/Assets/profile.jpg"/>
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Margin="12,20,0,0" Style="{StaticResource PhoneTextNormalStyle}" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="#4063A9"/>
</StackPanel>
<TextBlock Text="{Binding PostersComment}" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}" TextWrapping="Wrap" />
<StackPanel Orientation="Horizontal">
<TextBlock x:Name="{Binding PostedDate}" />
<TextBlock x:Name="{Binding PostedTime}" />
<TextBlock x:Name="{Binding IsApproved}" Visibility="Collapsed"/>
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
Problem was from the LongListSelector
Recreating the LongListSelector Solves the issue. I did this and it works fine

how to access DataCollection

I have a Pivot view in my WP8 app, and I'm trying to access the data collection from the view's class upon Click event "removePin".
The source of the data collection is another class called Pins.
how can I achieve that?
this is my snippet code for the XAML for that particular part
<phone:PivotItem Header="Pins">
<!-- Content Panel -->
<Grid x:Name="ContentPanel2" HorizontalAlignment="Left" Height="583" Margin="10,10,0,0" Grid.Row="1" VerticalAlignment="Top" Width="460">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400*"/>
<ColumnDefinition Width="0*"/>
<ColumnDefinition Width="87*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="lstData2" ItemsSource="{Binding DataCollection2, Source={StaticResource PinsCollection}}"
Grid.ColumnSpan="3" Foreground="#FF1D53D0" Height="583" VerticalAlignment="Bottom">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Tap="StackPanel_Tap">
<Image Margin="8" VerticalAlignment="Top" Source="{Binding ImageUri}"
Width="100" Height="100" />
<StackPanel Height="93" Width="259" >
<TextBlock Margin="8" Width="250" TextWrapping="Wrap" VerticalAlignment="Top" HorizontalAlignment="Left" Foreground="#FF1D53D0"
Text="{Binding Pinnedname}" Height="33" RenderTransformOrigin="0.5,0.5" FontFamily="Segoe WP SemiLight" FontSize="24" FontWeight="Bold" />
<TextBlock Width="155" Margin="8,0,8,8" VerticalAlignment="Top"
HorizontalAlignment="Left" Text="{Binding Status}" Foreground="#FF1D53D0" FontFamily="Segoe WP SemiLight" />
</StackPanel>
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Header="Remove Pin" Click="RemovePin_Click" Tag="{Binding pinId}"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!-- End of Content Panel -->
</Grid>
Create a custom command class:
public class CustomCommand : ICommand
{
Action _exec;
public CustomCommand(Action exec)
{
_exec = exec;
}
public void Execute(object parameter)
{
if (_exec != null) _exec();
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
Add it to the view model for elements of pins collection (I supposed it's PinItem)
public CustomCommand RemovePinCommand
{
get { return (CustomCommand)GetValue(RemovePinCommandProperty); }
set { SetValue(RemovePinCommandProperty, value); }
}
public static readonly DependencyProperty RemovePinCommandProperty =
DependencyProperty.Register("RemovePinCommand",
typeof(CustomCommand),
typeof(PinItem),
new UIPropertyMetadata(null));
In the constructor of that class implement your logic for this command:
RemovePinCommand = new CustomCommand(() =>
{
//delete this pin from its parent collection
});
final step is to bind the command to the menu item:
<toolkit:MenuItem Header="Remove Pin" Command="{Binding RemovePinCommand}"/>

Categories

Resources