How to set CheckBox margin dynamically in Silverlight - c#

I am creating CheckBoxes dynamically on my grid. Now I also want to set the margin(respected to the CheckBox) dynamically but not sure what would be the best way.
For example,
If there is only one CheckBox then the margin should be {5,0,0,0}
If there are two CheckBoxes then the first should have {5,0,0,0} and second should have {10,0,0,0} and so on.
I am concern with left margin. These check box creation is based on List<String>.
XAML:
<Grid x:Name="SynonymsGrid" Grid.Column="2" Margin="0,35,0,0" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>
CODE-BEHIND:
List<String> names = new List<string>() { "one", "two", "three" };
foreach (var name in names)
{
CheckBox chb = new CheckBox();
chb.Content = name;
chb.Margin = new System.Windows.Thickness { Left = 5, Top = 0, Right = 0, Bottom = 0 };
synonymsGrid.Children.Add(chb);
}
Above code will set all check boxes at one location which is obvious. I thought of using for loop but not sure what is the best approach.
Solution :
for (int i = 0; i < names.Count; i++)
{
CheckBox chb = new CheckBox();
chb.Content = names[i];
chb.Margin = new System.Windows.Thickness { Left = i * 150, Top = 0, Right = 0, Bottom = 0 };
synonymsGrid.Children.Add(chb);
}

Why do all this visual GUI operations in the code behind when there are Xaml constructs/controls that do the same thing?
To do this dynamically in Xaml...here are the steps.
First off, the StackPanel can evenly space out the checkboxes in a horizontal fashion instead of using a grid then margin'ing the controls to the right location. Note, you could even stop right here and replace your grid with a StackPanel and not even have a need for this question
But what makes it data driven (dynamic) in the Xaml paradigm, one uses the ItemsControl which specifies a panel or an area which will be our horizontal space (StackPanel) that will hold the dynamic items. Each of those dynamic items will be derived from a template containing a checkbox.
For example to achieve the three checkboxes based off of your Names list uses this :
Simply bind your list of names to ItemsControl which uses the StackPanel and a CheckBox using this Xaml:
<ItemsControl ItemsSource="{Binding Names}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding}"
Margin="5,0,0,0" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Related

c# - UWP ListView displays incorrect items upon rapid scrolling when it has a DataTemplate

I have a ListView that is intended to show every product within a database, and it works for the most part, but when I scroll down by dragging the scroll bar, the bottom items end up being incorrect.
XAML Definition:
<ListView x:Name="lst_Products" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="16,124,16,16" Width="300" ContainerContentChanging="lst_Products_ContainerContentChanging" Loaded="lst_Products_Loaded" BorderBrush="Black" BorderThickness="2" CornerRadius="16">
<ListView.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Value}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The data template is present so I can easily grab a product ID number with SelectedValue. According to some trusted community member (or whatever they call the prominent posters) on the MSDN forums said that's the only way to properly show a ListView when the ItemsSource is an ObservableCollection<KeyValuePair<int,RelativePanel>> while having a selectable value member.
The relevant C# code:
private async void lst_Products_Loaded(object sender, RoutedEventArgs e)
{
var products = await ProductManager.GetProducts();
ObservableCollection<KeyValuePair<int, RelativePanel>> productList = new(products);
lst_Products.ItemsSource = productList;
lst_Products.SelectedValuePath = "Key";
}
private void lst_Products_ContainerContentChanging(ListViewBase sender, ContainerContentChangingEventArgs args)
{
if (args.ItemIndex % 2 == 1)
{
args.ItemContainer.Background = new SolidColorBrush(Color.FromArgb(128, 128, 128, 128));
}
else
{
args.ItemContainer.Background = UIManager.GetDefaultBackground();
}
}
public static async Task<List<KeyValuePair<int, RelativePanel>>> GetProducts()
{
var productPanels = new List<KeyValuePair<int, RelativePanel>>();
var productIDs = await SqlHandler.ReturnListQuery<int>($"SELECT id FROM {productTable}");
var productNames = await SqlHandler.ReturnListQuery<string>($"SELECT name FROM {productTable}");
var panels = new List<RelativePanel>();
foreach(var name in productNames)
{
RelativePanel panel = new();
TextBlock productName = new()
{
Text = name
};
panel.Children.Add(productName);
panels.Add(panel);
}
for(int i = 0; i < productIDs.Count; i++)
{
productPanels.Add(new KeyValuePair<int, string>(productIDs[i], panels[i]));
}
return productPanels;
}
The call to SQL Handler just runs an SQL query and returns a list of the results. I can post the code if you need, but I can assure you there's no sorting going on.
A screenshot of what the list looks like. The bottom item should be "Coffee" - Button Test Product 2 is the second item in the list.
A screenshot of the SQL datatable with the "Coffee" product at the bottom where it should be.
In this case it's just the bottom item that's incorrect, however other times it has jumbled 5 or 6 entries near the bottom. This only seems to occur with the DataTemplate/ContentPresenter, but without that, the RelativePanel does not display correctly in the list. Eventually the list will show more information about the product and as far as I can tell, there's no good way to do that without converting the SQL data into a RelativePanel on the c# side.
I'm open to suggestions on solving either the jumbling problem with the template, or adjusting the xaml so that I don't need the template to display bulk sql data without needing the template but I'm at a loss.
c# - UWP ListView displays incorrect items upon rapid scrolling when it has a DataTemplate
The problem should be caused by listview virtualization, There are two ways to sloved this prolbem, one is disalbe listview virtualization by setting ItemsPanel as StackPanel like the following
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
And the other way is implement INotifyCollectionChanged interface for your model class. for more please refer to Data binding in depth
It's not good practice that useRelativePanel collection as datasoure, the better way is make RelativePanel in your DataTemplate and bind with mode class property.
For example
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Index}" />
<TextBlock Text="{Binding IsItem}" />
<Image Source="{Binding ImageSource}" Visibility="Collapsed" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>

How to dynamically create horizontal scrollable Gridview inside verticallly scollable page at Runtime

I want to create a page like Android playstore in which i have to create multiple horizontal scrollable Gridviews on the basis of data at runtime. As i am new to windows phone development i don't know how to create it dynamically. So Please provide any type of help or tutorial regarding this.
I have implemented the below code with this code i am able to produce the required result but the gridview items are not stacked horizontally.I want to make the items scroll horizontally So please provide any help with which required result can be achieved.I am attaching a screenshot for reference.
public void DesignUi()
{
GridViewItem grdItem = new GridViewItem();
for (int i = 0; i < 20; i++)
{
string backgroundColor = string.Empty;
StackPanel staParent = new StackPanel();
#region Header
StackPanel headerStack = new StackPanel();
headerStack.Background = new SolidColorBrush(Colors.Pink);
TextBlock textHeader = new TextBlock();
textHeader.Text = "Header :-" + i;
headerStack.Children.Add(textHeader);
#endregion
#region Body
StackPanel staBody = new StackPanel();
staBody.Background = new SolidColorBrush(Colors.Green);
#region Create Grid View
GridView grd = new GridView();
grd.SetValue(ScrollViewer.VerticalScrollModeProperty, ScrollMode.Disabled);
grd.SetValue(ScrollViewer.HorizontalScrollModeProperty, ScrollMode.Enabled);
ItemsPanelTemplate itmPanel = new ItemsPanelTemplate();
VirtualizingStackPanel vrStack = new VirtualizingStackPanel();
vrStack.Orientation = Orientation.Horizontal;
TextBlock textQ = new TextBlock();
textQ.Text = "";
vrStack.Children.Add(textQ);
itmPanel.SetValue(VirtualizingStackPanel.IsVirtualizingProperty, true);
itmPanel.SetValue(VirtualizingStackPanel.OrientationProperty, Orientation.Horizontal);
itmPanel.SetValue(ItemsControl.ItemContainerStyleProperty, Orientation.Horizontal);
ItemsControl itmCntrl = new ItemsControl();
itmCntrl.Items.Add(vrStack);
#region Create Gridview Items
for (int j = 0; j < 4; j++)
{
grdItem = new GridViewItem();
grdItem.Width = 100;
grdItem.Height = 150;
grdItem.Margin = new Thickness(5, 5, 5, 5);
grdItem.Background = new SolidColorBrush(Colors.Red);
TextBlock textGrd = new TextBlock();
textGrd.Text = "Item :-" + j;
grdItem.Content = textGrd;
grd.Items.Add(grdItem);
}
#endregion
#endregion
staBody.Children.Add(grd);
#endregion
staParent.Children.Add(headerStack);
staParent.Children.Add(staBody);
staLists.Children.Add(staParent);
}
}
Current Result Screenshot with the above code:---
Required Result Screenshot
I had to put this as an answer because the comment section was too limiting for this. So I better answer this and guide you towards the correct approach
OKay! there are better ways to do this. The best way and the easiest is via DataBinding. It'll reduce your code to almost nothing, and it'll be easier for you to design your GridView in XAML rather than doing it via c#. if you are not familiar with the concept of data binding and you want to implement it the way you're doing it now then I'll add to your solution that, the GridView would stack horizontally by setting the ItemsWrapGrid.Orientation property of your gridview to vertical to stack your elements horizontally and remember to set the scroll mode to horizontal too.
For the scroll mode: add the below to your GridView XAML
ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled"
For setting the ItemsWrapGrid Orientation Property:
string template =
"<ItemsPanelTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"><ItemsWrapGrid VerticalAlignment = \"Top\" "
+ " ItemWidth = \""
+ itemWidth
+ "\" Orientation = \"Vertical\"/></ItemsPanelTemplate> ";
yourgridview.ItemsPanel = (ItemsPanelTemplate)XamlReader.Load(template);
Please Note:
The Better and cleaner way to achieve this would be via DataBinding, The Below is the code for achieving this via DataBinding:
The XAML
<GridView Name="ViewView" HorizontalAlignment="Center" ItemTemplate="{StaticResource AllAppsTileData}" IsItemClickEnabled="True" SelectionMode="Single" Margin="10" ItemsSource="{Binding AppsToShow}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollMode="Enabled" ScrollViewer.VerticalScrollMode="Disabled">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical"/> <--Change this to Horizontal for vertically wrapping the items-->
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<GridView.ItemContainerStyle>
<Style TargetType="GridViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Margin" Value="5"/>
</Style>
</GridView.ItemContainerStyle>
</GridView>
The DataTemplate
To be defined in your <Page.Resources>
<DataTemplate x:Key="AllAppsTileData">
<Grid>
<Grid.Background>
<ImageBrush Stretch="Fill" ImageSource="{Binding AppImage}"/>
</Grid.Background>
<Grid>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.3"/>
</Grid.Background>
<TextBlock Text="{Binding AppName}" FontSize="20" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Grid>
</DataTemplate>
Your backing app class
public class AppDataClass
{
public string AppName { get; set; }
public string AppImage { get; set; } //The image would be something like ms-appx:///Assets/LOGO.png
}
Now that you have your architecture ready, there are two ways you can go about it from here,
You bind the ItemsSource property of the GridView to an ObservableCollection<AppDataClass> which can be populated by your code behind or preferably a ViewModel using the MVVM approach and each time the ObservableCollection<AppDataClass> changes, it raises the RasiePropertyChanged event from the interface INotifyPropertyChanged and the view automatically updates itself. This is a highly recommended approach as it keeps your UI and Business Logic on two different threads and either one of them would not interact with each other, they'll get the data via the ViewModel, this is the MVVM approach for more information on it use This article
As you explained that you're new to the Phone development, I would say forget all about the 1st point because it can be tough to grasp if you're new to the platform, what i'll recommend is the easy way,
From your code behind get the data into a List something like this,
List<AppDataClass> MyEntireData = new List<AppDataClass>();
MyEntireData = GetData();
where the GetData method is returning you a List<AppDataClass> and now simply after the MyEntireData is not empty or it's count is > 0 use, ViewView.ItemsSource = MyEntireData;
And you'll have a much more organized code which provides you the store way kinda layout.
And in future if you want to change the way the Tiles look you don't need to wrap your head to the c# generated XAML, you just need to modify the DataTemplate.
If there is anything do let me know in the comments section.

Presenting list of steps

I am working on Windows 8 application in C#/XAML.
I have a list of steps to show and the list can have one to many steps.
I have tried the GridView and ListView controls, but with those, it is not possible to have each element have its own height (because one step might have only one line of text, and the next one 3 lines, for example). The VariableSizedGridview does not help either.
What I am trying to achieve is something like the way cooking steps are shown in the Microsoft Bing Food & Drink app. So, steps are shown in rows in the first column, and when the end of the page is reached, it creates a second column, and so on. Like so :
Could anyone please help me find a way to achieve this?
What control to use and how?
It looks very simple, but I was not able to find any solution while searching online.
Thank you
Here is what I have done with the Gridview control (the Listview was quite similar) :
<Grid Name="gridSteps" Grid.Column="3" Margin="25,69,25,69">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="ÉTAPES" FontSize="22" FontWeight="Bold"></TextBlock>
<GridView Grid.Row="1" Name="gvGroupSteps" SelectionMode="None" IsHitTestVisible="False" VerticalAlignment="Top">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel Width="400">
<TextBlock Text="{Binding Order}" Margin="0,15,0,0" FontSize="20" Foreground="Bisque"></TextBlock>
<TextBlock Text="{Binding Description}" Margin="0,5,0,0" FontSize="18" TextWrapping="Wrap"></TextBlock>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Background="#FFC9C9C9">
<TextBlock Text="{Binding GroupName}" FontSize="20" FontWeight="SemiBold"></TextBlock>
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
</Grid>
You may want to post the XAML that you have tried. It sounds like to me that you need to nest your view items. Consider this very simple example:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<ListView>
<ListViewItem>Step 1</ListViewItem>
<ListViewItem>
<ListView>
<ListViewItem>Step 1a</ListViewItem>
<ListViewItem>Step 1b</ListViewItem>
<ListViewItem>Step 1c</ListViewItem>
</ListView>
</ListViewItem>
<ListViewItem>Step 2</ListViewItem>
</ListView>
</Grid>
I have tried the GridView and ListView controls, but with those, it is not possible to have each element have its own height
My recollection is that you can in fact have elements with different heights using those controls. These are both types of ItemsControl, which supports data templating, which in turn allows you to customize the appearance of each item, including its height.
That said, you may find that the simpler ListBox suits your needs in this case. It's hard to say without a code example or other details.
You should read MSDN's Data Templating Overview, which has a thorough discussion of the whole process, along with some good examples of what you can do. Pay particular attention to the section named "Choosing a DataTemplate Based on Properties of the Data Object". While a single template could still have variable height, clearly by using a different template according to your specific needs you can customize each item's style to your heart's content.
If this does not address your question, please provide a more detailed question. You should include a good, minimal, complete code example that shows clearly what you've tried, explaining precisely what that code does and how that's different from what you want it to do.
I have been looking all over the internet for a solution, but could not manage to find anything.
So i decided to do everything myself in C# code.
In short, in have a StackPanel with Orientation set to Horizontal, and I add a Grid to it and add rows to that Grid for every item i have. When the maximum height is reached (based on the screen Height), I add a new Grid to the StackPanel, and so on.
Here is my code if anyone needs it :
// Nombre de lignes maximal (16 lignes à 1080p)
int maxCharCount = (int)Window.Current.Bounds.Height * 16 / 1080;
spIngredients.Children.Clear();
foreach (var groupIngredient in db.Table<GroupIngredient>().Where(x => x.RecipeId == _currentRecipe.Id))
{
int linesCount = 0;
int row = 0;
var gGroup = new Grid();
spIngredients.Children.Add(gGroup);
gGroup.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
var groupName = new TextBlock() { Text = groupIngredient.Name, FontSize = 20, FontWeight = FontWeights.SemiBold, Margin = new Thickness(10) };
gGroup.Children.Add(groupName);
Grid.SetRow(groupName, row);
foreach (var ingredient in db.Table<Ingredient>().Where(x => x.GroupIngredientId == groupIngredient.Id))
{
// Nombre de lignes, split à 45 char
linesCount += 1 + ingredient.IngredientFull.Length / 45;
if (linesCount >= maxCharCount)
{
var gCol = new Grid();
spIngredients.Children.Add(gCol);
gCol.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
var col = new TextBlock() { Text = "", FontSize = 20, FontWeight = FontWeights.SemiBold, Margin = new Thickness(10) };
gCol.Children.Add(col);
gGroup = gCol;
row = 0;
linesCount = 0;
Grid.SetRow(col, row);
}
row++;
ingredient.Quantity = ingredient.Quantity * multiplier;
gGroup.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
var ingredientName = new TextBlock() { Text = ingredient.IngredientFull, Margin = new Thickness(10), FontSize = 18, TextWrapping = TextWrapping.Wrap, MaxWidth = 300 };
gGroup.Children.Add(ingredientName);
Grid.SetRow(ingredientName, row);
}
}

How to get a specific layout in databound list control

I want to layout my items in a Windows Phone 8.1 app, not silverlight, in the following order:
I did some research and tried different panels, but I can't find the right ones :[
I could use a grid and achive that design, BUT I want to add items over a binding and then I would have to change the grid somehow :/
xaml Layout
<Page.DataContext>
<uc:Test/>
</Page.DataContext>
<ScrollViewer>
<ItemsControl ItemsSource="{Binding t}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Aqua"
BorderThickness="3"
Width="100" Height="100">
<TextBlock Text="{Binding}"/>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
test.cs
public class Test
{
public ObservableCollection<string> t { get; set; }
public Test()
{
t = new ObservableCollection<string>();
t.Add("a");
t.Add("b");
t.Add("c");
t.Add("d");
t.Add("e");
}
}
Edit:
ALSO, I did write a wrong information in the comment below, sorry.
Every Item has the same width, so count and width, will/would give me the position in column and row.
Implementation of PrepareContainerForItemOverride so far:
public class ExtendedItemsControl : ItemsControl
{
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
var grid = element as ContentPresenter;
var count = 0; // <- Count of Items in the Grid
var width = 0; // <- width of the current Element
//if (count * width / grid.ActualWidth > 1)
// grid.RowDefinitions.Add(new RowDefinition());
Grid.SetRow(grid, 0);
}
}
You can use a Grid along with an ItemsControl to achieve the ItemsSource binding:
First, set the Grid as the ItemsControl's ItemsPanel
Second, subclass the ItemsControl to set the appropriate Grid.Row and Grid.Column properties on its children
For the first part (it looks from the picture like you have 4 columns and 3 rows):
<local:ExtendedItemsControl ItemsSource="{Binding MyItems}">
<local:ExtendedItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</local:ExtendedItemsControl.ItemsPanel>
</local:ExtendedItemsControl>
For the second part, I suggest overriding OnItemsChanged, and setting the Grid attached properties on each item container as needed. You could do this by using the implicit sequence of the items:
public class ExtendedItemsControl : ItemsControl
{
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
var item2 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[1]);
Grid.SetColumn(item2, 1);
var item3 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[2]);
Grid.SetColumn(item3, 2);
Grid.SetColumnSpan(item3, 2);
var item4 = this.ItemContainerGenerator.ContainerFromItem(e.NewItems[3]);
Grid.SetRow(item4, 1);
// etc ...
}
}
The above assumes that your source collection doesn't not change once bound -- if it does change, you might consider overriding PrepareContainerForItemOverride instead, and setting its Grid Row/Column properties with reference to a property on the item model ("ItemIndex" or whatever):
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
{
base.PrepareContainerForItemOverride(element, item);
var contentPresenter = (ContentPresenter)element;
var itemModel = (MyItemModel)item;
switch (itemModel.ItemIndex)
{
case 1:
Grid.SetColumn(contentPresenter, 1);
break;
case 2:
Grid.SetColumn(contentPresenter, 2);
Grid.SetColumnSpan(contentPresenter, 2);
break;
// etc
}
}
There isn't a standard control that will give you the layout you want for arbitrary numbers of different sized items without some custom placement code, but you can customize controls depending on what exactly you need.
Mark Rideout created a customized GridView sample for Windows Store 8.0 at How To: Create a Variable Sized Grouped GridView (like the store) and the techniques you'll use for a Windows Phone Runtime app will be essentially the same. In his control he overrode the PrepareContainerForItemOverride function to look at the individual data items to see if they should be small, medium, or large sized, and then set their columns and spans appropriately in a VariableSizedWrapGrid.
If you want the exact positioning you show (rather than lining things up) and want to limit to 7 then you could set the ItemsPanel to a Grid instead of the VariableSizedWrapGrid and set the items into specific rows and columns in the same way.

Listbox databinding NewItemPlaceholder

I have an observable collection bound to a list box.
The collection has 2 items, but the list box is showing 3 items (e.g. the 2 items that are actually in the observable collection and an additional item for the NewItemPlaceholder.
I want it only to show the 2 items.
Below is my XAML.
<ListBox MinHeight="20" MinWidth="20" Name="MultipleSelectionsMultipleWagersListBox" Visibility="{Binding Path=Coupon.BarcodeText, Converter={StaticResource CouponBarcodeToVisibilityConverter1}, ConverterParameter=994450_994550}" Height="AUto" Width="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="5"
ItemsSource="{Binding Path=BetViewModels}" Grid.Row="1" Grid.Column="1" >
<ListBox.ItemTemplate>
<DataTemplate>
<View:BetView DataContext="{Binding}" Name="ThisBet" Margin="5"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is the c#
private ObservableCollection<BetViewModel> _betViewModels = new ObservableCollection<BetViewModel>();
public ObservableCollection<BetViewModel> BetViewModels
{
get { return _betViewModels; }
set
{
if (Equals(value, _betViewModels)) return;
_betViewModels = value;
OnPropertyChanged("BetViewModels");
}
}
Here is the code to populate the betViewModels:
var betViewModel = new BetViewModel { Bet = new Bet() };
betViewModel.Bet.SelectionName = "Chelsea";
betViewModel.Bet.Price = "4/9";
betViewModel.Bet.Market = "90 Minutes";
betViewModel.Bet.ExpectedOdd = DateTime.Now;
BetViewModels.Add(betViewModel);
betViewModel = new BetViewModel { Bet = new Bet() };
betViewModel.Bet.SelectionName = "Chelsea";
betViewModel.Bet.Price = "4/9";
betViewModel.Bet.Market = "90 Minutes";
betViewModel.Bet.ExpectedOdd = DateTime.Now;
BetViewModels.Add(betViewModel);
How Do I switch of this from showing the additional item for the new item place
Here is an image of it displaying the placeholder
The DataGrid supports adding new rows, which have to start out blank. If your ItemsSource is bound to both a ListBox/ItemsControl and a DataGrid, you need to set the DataGrid 'CanUserAddRows' property to 'False'.
Where I found the answer: http://www.mindstick.com/Forum/1519/How%20do%20I%20remove%20a%20listbox%20new%20item%20placeholder
There's nothing in your code that should be adding an extra empty item. There may be some other code adding to BetViewModels or there may be a change happening to the generated ICollectionView for the collection if you have it bound to something else that you're not showing, like an editable DataGrid.
did your sample code also provide this issue?
how much items contains your _betViewModels.count in debugging there are really only 2 Items?
it seems you added an empty BetViewModel at the End
i would suggest check your logic which provides populates your items
if it is a loop it should (counter<yourDatasource.Count) just for example

Categories