Why there is exception on grid creation - c#

I have to create a grid array the size of this array is determined dynamically.
My try to do this is:
int size = 4; //This "size" will be determined dynamically.suppose i got 4 here
Grid[] rowgrid = new Grid[size];
for (int i = 0; i < size; i++)
{
rowgrid[i].RowDefinitions.Add(new RowDefinition());
}
It don't give any error but when i run it gives exception :
The object reference is not set to an instance of an object.
EDIT:
I want to use array because : after intializing before i have to do like this :
rowgrid[0].Opacity=0.1;
rowgrid[1].Opacity=0.3;
rowgrid[2].Opacity=0.5;
If you suggest me not work programatically then i want to inform in avance that i know that well but i am obliged to do this because i am working in already developed project and no more options are there. It would be a big help if some one bring me to come out of this error or any other alternative to achieve this.

If you want a Grid with differents Rows or Columns. You can use UniformGrid, columns and rows properties are binding.
So,
<UniformGrid Name="uniformGrid1" Rows="{Binding NumberOfRows}" Columns="{Binding NumberOfColumns}">
<Button Content="Button1" Grid.Row="0" Grid.Column="0" />
<Button Content="Button2" Grid.Row="0" Grid.Column="2" />
</UniformGrid>
In your code
private int _numberOfRows;
public int NumberOfRows
{
get { return _numberOfRows; }
set { _numberOfRows= value; RaisePropertyChanged("NumberOfRows"); }
}
private int _numberOfColumns;
public int NumberOfColumns
{
get { return _numberOfColumns; }
set { _numberOfColumns= value; RaisePropertyChanged("NumberOfColumns"); }
}
public MainViewModel()
{
NumberOfColumns = 3;
NumberOfRows = 2;
}

Related

How can I implement a carousel of images in WPF where the selected item is always the first one?

I am creating a WPF application to act as a front end for a video games library and I'm attempting to mimic the Netflix UI. One of the features in this application is to cycle through images of games to select which game you want to play.
The desired behavior is different than the behavior when arrowing through the items in a ListBox: when you arrow through items in a ListBox, your selection moves up and down. The behavior I'm looking to implement is that as you arrow through the items, the selected item is always at the first position and the items are cycling across the selector. The term for this would be a carousel where the selected item is at index 0.
I've implemented this poorly and to give some context, here's a picture of how my interface currently looks:
My current implementation
To achieve this, I believe what I should do is extend the StackPanel class or maybe implement my own Panel. But details on custom panels are a bit complicated and hard to come by. I want to show what I've done to this point to get this working but I'm very unhappy with these implementations and I'd like to get some advice on what direction I should go for a proper implementation.
Here are some details on what I've tried.
The screenshot above is a result of a GameList class that I created which implements INotifyPropertyChanged and includes properties for 15 different games.
private GameMatch game0;
public GameMatch Game0
{
get { return game0; }
set
{
if (game0 != value)
{
game0 = value;
PropertyChanged(this, new PropertyChangedEventArgs("Game0"));
}
}
}
private GameMatch game1;
public GameMatch Game1
{
get { return game1; }
set
{
if (game1 != value)
{
game1 = value;
PropertyChanged(this, new PropertyChangedEventArgs("Game1"));
}
}
}
// identical code for games 2-10
private GameMatch game11;
public GameMatch Game11
{
get { return game11; }
set
{
if (game11 != value)
{
game11 = value;
PropertyChanged(this, new PropertyChangedEventArgs("Game11"));
}
}
}
private GameMatch game12;
public GameMatch Game12
{
get { return game12; }
set
{
if (game12 != value)
{
game12 = value;
PropertyChanged(this, new PropertyChangedEventArgs("Game12"));
}
}
}
I've laid the images out in my XAML and added enough so that they will run off the edge of the screen:
<StackPanel Name="GameImages" Orientation="Horizontal">
<Border BorderThickness="2" BorderBrush="AntiqueWhite">
<Image Name="Image_Game1" Source="{Binding CurrentGameList.Game1.FrontImage}"/>
</Border>
<Image Source="{Binding CurrentGameList.Game2.FrontImage}"/>
<!-- identical images for games 3-10 -->
<Image Source="{Binding CurrentGameList.Game11.FrontImage}" />
<Image Source="{Binding CurrentGameList.Game12.FrontImage}" />
</StackPanel>
I implemented a ListCycle class which can take any arbitrary list and a count of items that you want to cycle. In case it helps, here's the code for the ListCycle. It takes care of cycling the lists by tracking the index of items in list that should be displayed on screen in a given position.
public class ListCycle<T>
{
// list of games or whatever you want
public List<T> GenericList { get; set; }
// indexes currently available to display
// will cycle around the size of the generic list
public int[] indices;
public ListCycle(List<T> genericList, int activeCycleCount)
{
GenericList = genericList;
indices = new int[activeCycleCount];
InitializeIndices();
}
private void InitializeIndices()
{
if (GenericList != null)
{
int lastIndex = -1;
for (int i = 0; i < indices.Length; i++)
{
indices[i] = GetNextIndex(lastIndex);
lastIndex = indices[i];
}
}
}
private int GetNextIndex(int currentIndex)
{
currentIndex += 1;
if (currentIndex == GenericList.Count)
{
currentIndex = 0;
}
return currentIndex;
}
private int GetPreviousIndex(int currentIndex)
{
currentIndex -= 1;
if (currentIndex == -1)
{
currentIndex = GenericList.Count - 1;
}
return currentIndex;
}
public int GetIndexValue(int index)
{
return indices[index];
}
public T GetItem(int index)
{
return GenericList[indices[index]];
}
public void CycleForward()
{
for (int i = 0; i < indices.Length; i++)
{
if (i + 1 < indices.Length - 1)
{
indices[i] = indices[i + 1];
}
else
{
indices[i] = GetNextIndex(indices[i]);
}
}
}
public void CycleBackward()
{
for (int i = indices.Length - 1; i >= 0; i--)
{
if(i - 1 >= 0)
{
indices[i] = indices[i - 1];
}
else
{
indices[i] = GetPreviousIndex(indices[i]);
}
}
}
}
So when you press right, I cycle forward and reset the game images. When you press left, I cycle backward and reset the game images. The RefreshGames method takes care of updating all of those game properties in my game list.
private void RefreshGames()
{
Game0 = gameCycle.GetItem(0);
Game1 = gameCycle.GetItem(1);
Game2 = gameCycle.GetItem(2);
Game3 = gameCycle.GetItem(3);
Game4 = gameCycle.GetItem(4);
Game5 = gameCycle.GetItem(5);
Game6 = gameCycle.GetItem(6);
Game7 = gameCycle.GetItem(7);
Game8 = gameCycle.GetItem(8);
Game9 = gameCycle.GetItem(9);
Game10 = gameCycle.GetItem(10);
Game11 = gameCycle.GetItem(11);
Game12 = gameCycle.GetItem(12);
}
This approach works but it doesn't work well. It's not dynamic, it doesn't scale well and it doesn't perform all that well. Arrowing through images one at a time performs just fine but trying to quickly move through them, is a bit slow and feels clunky. It's not a very good user experience.
I tried a second approach, using a listbox bound the to my list of games. And to cycle the games to the left, I would remove the first item from my list of games and insert it at the end of the list. To go to the right, I would remove the item at the end of the list and insert it at index 0. This also worked but it didn't perform very well either.
So I'm looking for suggestions on a better way to implement this that would give better performance (smoother scrolling) and be more dynamic (i.e. this approach may not work well on an ultrawide monitor - 12 games may not be enough depending on the widths of the images). I'm not looking for anyone to solve it for me but point me in the right direction as I'm very new to WPF.
My feeling is that I should be extending the stack panel class and changing the way you cycle through the items or maybe creating my own panel. Can anyone confirm if this is the best approach and if so point me to some good resources to help me understand how to create a custom panel that changes the way navigation is done? I've been reading articles on creating custom panels to try to get my head around that process.
Being new to WPF, I want to make sure I'm not going down a rabbit hole or trying to reinvent a wheel that already exists. So the question is whether a custom panel is the right approach to solving this problem?
I believe what I should do is extend the StackPanel class
WPF encourages composition of existing Controls over inheritance; in your case inheriting the StackPanel looks too complicated for your purpose when you could achieve the same with your second approach:
I would remove the first item from my list of games and insert it at the end of the list
This indeed looks more like idiomatic WPF, especially if you try to follow the MVVM design pattern.
or maybe creating my own panel
This is not an easy step especially if you're new to WPF but that would be very interesting for you. That could be a way to go, especially if you internally rely on a StackPanel (composition) instead of inheriting from it.
Example implementation with an ItemsControl
I will use an ItemsControl which can display a collection of data for you (in your case, you have some GameMatch).
First define the data behind the interface, ie a collection of GameMatch. Let's give each GameMatch a name and a variable IsSelected which tells if the game is selected (ie in first position). I'm not showing the INotifyPropertyChanged implementation but it should be there for both properties.
public class GameMatch : INotifyPropertyChanged {
public string Name { get => ...; set => ...; }
public bool IsSelected { get => ...; set => ...; }
}
Your carousel interface is interested in a collection of GameMatch, so let's create an object to model this.
Our graphical interface is gonna bind to the Items property to display the collection of games.
It is also gonna bind to the two commands that are implemented such as to shift the list to the left or to the right. You can use the RelayCommand to create commands. In a nutshell, a Command is simply an action that gets executed and that you can easily refer to from your interface.
public class GameCollection {
// Moves selection to next game
public ICommand SelectNextCommand { get; }
// Moves selection to previous game
public ICommand SelectPreviousCommand { get; }
public ObservableCollection<GameMatch> Items { get; } = new ObservableCollection<GameMatch> {
new GameMatch() { Name = "Game1" },
new GameMatch() { Name = "Game2" },
new GameMatch() { Name = "Game3" },
new GameMatch() { Name = "Game4" },
new GameMatch() { Name = "Game5" },
};
public GameCollection() {
SelectNextCommand = new RelayCommand(() => ShiftLeft());
SelectPreviousCommand = new RelayCommand(() => ShiftRight());
SelectFirstItem();
}
private void SelectFirstItem() {
foreach (var item in Items) {
item.IsSelected = item == Items[0];
}
}
public void ShiftLeft() {
// Moves the first game to the end
var first = Items[0];
Items.RemoveAt(0);
Items.Add(first);
SelectFirstItem();
}
private void ShiftRight() {
// Moves the last game to the beginning
var last = Items[Items.Count - 1];
Items.RemoveAt(Items.Count - 1);
Items.Insert(0, last);
SelectFirstItem();
}
}
The key here is the ObservableCollection class which will tell the view whenever it changes (for example, everytime we move items around inside it) so the view will update to reflect this.
Then, the view (your XAML) should specify how to display the collection of games. We're gonna use an ItemsControl laying out items horizontally:
<StackPanel>
<ItemsControl ItemsSource="{Binding Items}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Margin="10" Background="Beige" BorderBrush="Black" Width="150" Height="50">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="1" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="true">
<Setter Property="BorderThickness" Value="5" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<TextBlock Text="{Binding Name}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Previous" Command="{Binding SelectPreviousCommand}"/>
<Button Content="Next" Command="{Binding SelectNextCommand}"/>
</StackPanel>
</StackPanel>
Notice the ItemsControl ItemsSource="{Binding Items}" which tells the ItemsControl to display all the objects in the Items property. The ItemsControl.ItemsPanel part tells to lay them out in an horizontal StackPanel. The ItemsControl.ItemTemplate part explains how each game should be displayed, and the DataTrigger within tells WPF to increase the border thickness for the selected item. Finally, the StackPanel at the bottom displays two Button which call SelectPreviousCommand and SelectLeftCommand in our GameCollection.
Finally, you should set the DataContext of the whole thing to a new GameCollection:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
DataContext = new GameCollection();
}
}
From there you can customize the UI as you'd like.
Animations and smooth scrolling
That is a whole other topic but you could for example trigger a translation animation of all your items when clicking one of the buttons.
I'll try and point you in the right direction. If you haven't already checked it out, I would try to make your application follow the MVVM pattern. In your case, the ViewModel would have an ObservableCollection of "Games". You would then bind your ItemsControl's source to that collection.
As far as getting the carousel to work, I think the path you will want to go down is creating a custom ItemsControl or ListBox. You can override the styling and create some custom behavior to get the carousel to work how you would like it to.
I can probably help out more if you have a more specific question.

Alternate row color ListView xamarin forms

I have bind on my ListView, an ObersvableCollection.
And i want to alternate my row color of my ListView.
I found lot of code, but didn't work for me... If you can share an example/sample !
Like this :
But i don't know how i can do that ?
I work with Visual Studio 2015 / Xamarin forms.
My project must be work with Android and IOS.
Thank for your help!
You can use a custom ListView for that. This works, if your Cell inherits from ViewCell.
public class AlternatingListView : ListView
{
public AlternatingListView(ListViewCachingStrategy cachingStrategy) : base(cachingStrategy)
{
}
protected override void SetupContent(Cell content, int index)
{
base.SetupContent(content, index);
var viewCell = content as ViewCell;
viewCell.View.BackgroundColor = index % 2 == 0 ? Color.Blue : Color.Red;
}
}
There's no built in way to do this with XF. The simplest approach would be to include an Index property in your Item model (you would have to set it manually as you add it to your List/Collection) that determines the color. You could then bind the RowColor property to your ItemTemplate.
public class MyItem {
public int Index { get; set; }
public string Name { get; set; }
public Color RowColor {
get {
if (Index % 2) == 0))
return Color.Red;
else
return Color.Blue;
}
}
}
You could also use a ValueConverter to determine the Color based on the Index row - this would free your model from having to determine it's own color, which would be a cleaner implementation.
Another option would be adding it to the objects contained within the listview itself before passing the listview into the binding context.
So for example, when requesting lists from an API and deserializing them, you can then proceed to iterate and assign a background color property to each object within the list:
var response = client.GetAsync(EndPointHelper.GetEndPoint("MaintenanceForEquipment") + "/" + equipmentid).Result;
var content = await response.Content.ReadAsStringAsync();
var contentmaintenances = JsonConvert.DeserializeObject<List<Maintenance>>(content);
var count = 1;
foreach (var maint in contentmaintenances)
{
maint.BackgroundColor = count % 2 == 0 ? "#A1DBE4" : "#155DB0";
maint.TextColor = count % 2 == 0 ? "#529CFF" : "#e9ecf0";
count++;
}
From there, you can access it in the ItemTemplate within your list view after assigning the records accessed to the binding context:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="{Binding BackgroundColor}"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Label Text="{Binding EquipmentName}"
TextColor="{Binding TextColor}" FontSize="Medium"/>
<Label Text="{Binding StartDateString}" TextColor="{Binding TextColor}"></Label>
<Label Text="{Binding MaintenanceTypeName}"
HorizontalOptions="EndAndExpand"
TextColor="{Binding TextColor}" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
If you want to use fewer iterations within your Xamarin code, you can implicitly generate the background color via whatever API you're working with assuming you have access to that as well so it only needs to be assigned one time and accessed again on the client side after calling the API.
Hope this helps anyone looking through this old question for another possible solution.
You can use a custom view cell. I've written a custom view cell in my project and used XFGloss(XFGloss is an add-on for Xamarin.Forms projects that adds new properties to the standard XF page and control classes) to make the listView's rows colorful. Your listView will not lose the haptic feedback with XFGloss. It works with grouped listViews too. The custom viewCell which I used is :
public class MyViewCell : ViewCell
{
private Color BackgroundColor
{
get => CellGloss.GetBackgroundColor(this);
set => CellGloss.SetBackgroundColor(this, value);
}
public Color EvenColor { get; set; }
public Color UnevenColor { get; set; }
protected override void OnAppearing()
{
base.OnAppearing();
if (!(Parent is ListView listView))
throw new Exception(
$"The Binding Context is not {typeof(ListView)}. This component works only with {typeof(ListView)}.");
int index;
if (listView.IsGroupingEnabled)
{
index = listView.TemplatedItems.GetGroupAndIndexOfItem(BindingContext).Item2;
}
else
{
index = listView.TemplatedItems.IndexOf(this);
}
if (index != -1)
BackgroundColor = index % 2 == 0 ? EvenColor : UnevenColor;
}
}
and its usage in the xaml file is simple as below line :
<components:MyViewCell EvenColor="White" UnevenColor="#eeeeee">

x:Bind in windows 10 Mode One way

I am trying to update the list which is Bound to ListBox , When the scroll bar reaches end.I need to update the list and show the changes in UI also.Here it is not updating automatically.Can someone please help me in fulfilling my requirement.
If i tried to use TwoWay mode, It shows below error:
Error : Invalid binding path 'itemsList' : Cannot bind type 'System.Collections.Generic.List(System.String)' to 'System.Object' without a converter
<ScrollViewer
x:Name="sv"
ViewChanged="OnScrollViewerViewChanged">
<ListBox x:Name="listView"
HorizontalAlignment="Left"
Height="Auto"
VerticalAlignment="Top"
Width="172"
ItemsSource="{x:Bind itemsList, Mode=OneWay}"/>
</ScrollViewer>
and the code
public List<String> itemsList = new List<string>();
private void OnScrollViewerViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
var verticalOffset = sv.VerticalOffset;
var maxVerticalOffset = sv.ScrollableHeight; //sv.ExtentHeight - sv.ViewportHeight;
if (maxVerticalOffset < 0 ||
verticalOffset == maxVerticalOffset)
{
// Scrolled to bottom
Util.debugLog("REACHED BOTTOM");
int i;
// itemsList = null;
itemsList.Clear();
for (i = 0; i < 20; i++)
{
itemsList.Add("Item number " + i + 900);
}
}
else
{
// Not scrolled to bottom
// rect.Fill = new SolidColorBrush(Colors.Yellow);
}
}
Here(In below link) is the answer for my question.Thanks alot for all who tried to answer my question.
https://social.technet.microsoft.com/Forums/en-US/7c730558-f933-4483-8d5b-1710d19f99de/xbind-in-windows-10-mode-one-way-i-am-trying-to-update-the-bind-list-when-scrollview-reached-to?forum=wpf

How to set the SelectedItem when having databound ListPicker?

I have a CartPage in WindowsPhone App. It shows Items in cart with their selected quantities.
I use a ListPicker to change the quantity. Now I have two questions,
How to set the default Quantity in ListPicker (I am getting the Quantity of product from localstorage).
When I select the quantity from ListPicker, How to save it into variable?
<Grid.Resources>
<DataTemplate x:Name="PickerFullModeItemTemplate">
<StackPanel Orientation="Horizontal" Margin="16 21 0 20" >
<TextBlock Name="TextQuantity" Text="{Binding Quantity}" Margin="16 0 0 0" FontSize="43" FontFamily="{StaticResource PhoneFontFamilyLight}"/>
</StackPanel>
</DataTemplate>
</Grid.Resources>
<toolkit:ListPicker toolkit:TiltEffect.IsTiltEnabled="True" Name="QuantityBox" Margin="264,91,142,36" Background="#FFA05E6A" FullModeItemTemplate="{StaticResource PickerFullModeItemTemplate}" BorderBrush="#FF8D7373" Foreground="#FF310836" FontSize="20" SelectionChanged="QuantityBox_SelectionChanged" MouseEnter="QuantityBox_MouseEnter" BorderThickness="1"/>
public class ListQuantityClass
{
public int Quantity { get; set; }
}
List<ListQuantityClass> QuantitySource = new List<ListQuantityClass>();
for (int i = 1; i <= 20; i++)
{
QuantitySource.Add(new ListQuantityClass() { Quantity = i });
}
Custom.QuantityBox.ItemsSource = QuantitySource;
Both the below lines are giving me error:
Custom.QuantityBox.SelectedItem = cart.ProductQuantity;
singletonInstance.QuantityChanged = int.Parse(QuantityBox.SelectedItem.ToString());
Actually Its obvious QuantityBox.SelectedItem WONT WORk because ListPicker is Databdound to QuantitySource list. What to use instead of QuantityBox.SelectedItem?
Since this is a two part question I will split it up into two sections.
How to set the default Quantity in ListPicker (I am getting the
Quantity of product from localstorage).
You can set the SelectedItem only to an item in the ItemSource. Using your example,
public partial class MainPage : PhoneApplicationPage
{
List<ListQuantityClass> QuantitySource = new List<ListQuantityClass>();
// Constructor
public MainPage()
{
InitializeComponent();
for (int i = 1; i <= 20; i++)
{
QuantitySource.Add(new ListQuantityClass() { Quantity = i });
}
my_listpicker.ItemsSource = QuantitySource;
// setting default value to 3
my_listpicker.SelectedItem = QuantitySource[2];
// fancy search and set
// my_SetSelectedItemBasedOnQuantity(my_listpicker, 4); // this will set it to 4
}
}
When I select the quantity from ListPicker, How to save it into
variable?
This is a much more involved problem. You can loop through the Items in the ItemSource and check to see if it equals the SelectedItem and saved it that way. But I much prefer if you use an event, like so.
private void my_listpicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
try
{
var listpicker = sender as ListPicker;
if (listpicker != null)
{
var selected_item = listpicker.SelectedItem as ListQuantityClass;
int quantity = selected_item.Quantity;
// TODO: Save the value in quantity to a file or send it to a webservice
}
}
catch (Exception ex)
{
string error_message = ex.Message;
}
}
XAML
<Grid.Resources>
<DataTemplate x:Name="PickerItemTemplate">
<TextBlock Text="{Binding Quantity}" FontSize="43"/>
</DataTemplate>
<DataTemplate x:Name="PickerFullModeItemTemplate">
<TextBlock Text="{Binding Quantity}" Margin="16 0 0 0" FontSize="43"/>
</DataTemplate>
</Grid.Resources>
<toolkit:ListPicker Header="my list picker demo" x:Name="my_listpicker" ItemTemplate="{StaticResource PickerItemTemplate}" FullModeItemTemplate="{StaticResource PickerFullModeItemTemplate}" SelectionChanged="my_listpicker_SelectionChanged" MaxHeight="300"/>
Function to set SelectedItem based on Quantity
private void my_SetSelectedItemBasedOnQuantity(ListPicker lp, int quantity)
{
// first search for quantity if a match is found set it
try
{
foreach (ListQuantityClass lqc in lp.ItemsSource)
{
// match found
if (lqc.Quantity == quantity)
{
lp.SelectedItem = lqc;
}
}
}
catch (Exception ex)
{
string error = ex.Message;
}
}
I think you cannot use SelectedItem to set the selected item.You should set the SelectedIndex property instead. SelectedItem is used to get the selected item.Although the docs say that it can be used to set the selected item,I have never seen any practical implementation of the same.

Failing to generate dynamic Checkboxes

I am working on a WPF where I need to dynamically generate Checkboxes 16 times.
XAML:
<Checkboxes Height="14" Command="{Binding CheckboxesGen}" Margin="0" Name="checkBox1" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" />
Using above way, It will be inefficient if I write down this Checkboxes 16 times and have individual Button Click Command for them. I would ideally want to generate them 16 times and have one common method in my viewmodel class as follows:
private ICommand mCheckboxesGen;
public ICommand CheckboxesGen
{
get
{
if (mCheckboxesGen== null)
mCheckboxesGen= new DelegateCommand(new Action(mCheckboxesGenExecuted), new Func<bool>(mCheckboxesGenCanExecute));
return mCheckboxesGen;
}
set
{
mCheckboxesGen= value;
}
}
public bool mCheckboxesGenCanExecute()
{
return true;
}
public void mCheckboxesGenExecuted(some INDEX parameter which gives me selected Checkboxes )
{
// Have a common method here which performs operation on each Checkboxes click based on INDEX which determines which Checkboxes I have selected
}
I had faced the same situation in my C++ app. I had done it in my C++ app as follows:
for(int j = 0; j < 16; j ++)
{
m_buttonActiveChannels[j] = new ToggleButton();
addAndMakeVisible(m_buttonActiveChannels[j]);
m_buttonActiveChannels[j]->addButtonListener(this);
}
//Checking which Checkboxes is clicked
unsigned bit = 0x8000;
for(int i = 15; i >= 0; i--)
{
if(0 != (value & bit)) //Value has some hardcoded data
{
m_buttonActiveChannels[i]->setToggleState(true);
}
else
{
m_buttonActiveChannels[i]->setToggleState(false);
}
bit >>= 1;
}
Hence using this generates it 16 times and has one method which performs operation based on index i.
Using a similar approach or any other approach, How can I achieve it in my wpf app? :)
Please help :)
How about something like this?
<ItemsControl ItemsSource="{Binding CollectionOfObjectsThatRepresentYourCheckBox}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Checkbox Content="{Binding DisplayText }" Checked="{Binding Checked}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
you would need to populate your collection on objects on load or when a command was executed, then you could react to items being checked in the model that you create for it..
public class CheckBoxClass
{
public int Index {get; set;}
public string DisplayText {get; set}
private bool _checked;
public bool Checked
{
get { return _checked;}
set {
_checked = value
doSomethingWhenChecked();
}
}
ObservableCollection<CheckBoxClass> CollectionOfObjectsThatRepresentYourCheckBox = SomeMethodThatPopulatesIt();
this is a much cleaner way to do this and instead of generating the controls you will be just binding to a list of your objects that will be represented by a check box.
Define a viewmodel for the checkboxes, this class will have an Index property and the command implementation based on it. Add an ObservableCollection of checkboxes viewmodels to your current viewmodel. In the view add an ItemsControl bound to this collection with a proper ItemTemplate. You can now add as many checkboxes as you want dynamically in the viewmodel.

Categories