Dynamic grid within a scrollviewer - c#

I have a grid which contains dynamically created pairs of textblocks and buttons. I can continue to add these objects infinitely but after they fill the grid, the new pairs are not visible.
I have tried to solve this by putting the grid inside a scrollviewer and each time a new pair is added, increasing the height/maxheight of both the grid and the scrollviewer. But I still cannot see the new elements after the screen is filled.
This is from my .xaml file
<ScrollViewer x:Name="ContentScroll" Grid.Row="1">
<Grid x:Name="ContentPanel" HorizontalAlignment="Left" Height="577" Grid.Row="1" VerticalAlignment="Top" Width="470"> </Grid>
</ScrollViewer>
and this is from my .xaml.cs file
List<TextBlock> textblock_list = new List<TextBlock>();
List<Button> button_list = new List<Button>();
for(int i = 0; i < classlist.Count(); i++)
{
TextBlock tb = new TextBlock();
tb = SetTextBlock(tb, i);
tb.Text = classlist[i].name;
textblock_list.Add(tb);
ContentPanel.Children.Add(textblock_list[i]);
Button bt = new Button();
bt = SetButton(bt, i);
button_list.Add(bt);
ContentPanel.Children.Add(button_list[i]);
Grid.SetColumn(bt, i);
}
Any thoughts on a solution? Thanks in advance.

Try removing the Height="577" from your grid

Related

Create "table style" ListView in UWP and XAML (C#)

I'm wondering if there is any way I can create a "table like" ListView in a UWP Windows 10 app? I need some sort of table where I can allow a user to browse and select files and then put the selected files into a list, sort of like a details view that you see in Windows explorer with column headers and rows that I can insert programmatically like:
string[] item = { "D:\\Music\\MyAudioFile.mp3", "MP3", "12MB" }
listview1.Items.Add(item);
Anyone have any ideas what I can use for this?
Thanks
Thanks Lindexi, that pointed me in the right direction... Here is the code I got working...
C# backend code:
// Create a new StackPanel to insert as a ListViewItem
StackPanel myStack = new StackPanel();
myStack.HorizontalAlignment = HorizontalAlignment.Stretch;
myStack.VerticalAlignment = VerticalAlignment.Stretch;
myStack.Orientation = Orientation.Horizontal;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv1 = new ListViewItem();
lv1.Content = "Test Content";
lv1.Width = 400;
lv1.HorizontalAlignment = HorizontalAlignment.Stretch;
lv1.VerticalAlignment = VerticalAlignment.Stretch;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv2 = new ListViewItem();
lv2.Content = "Test Content";
lv2.Width = 100;
lv2.HorizontalAlignment = HorizontalAlignment.Stretch;
lv2.VerticalAlignment = VerticalAlignment.Stretch;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv3 = new ListViewItem();
lv3.Content = "Test Content";
lv3.Width = 100;
lv3.HorizontalAlignment = HorizontalAlignment.Stretch;
lv3.VerticalAlignment = VerticalAlignment.Stretch;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv4 = new ListViewItem();
lv4.Content = "Test Content";
lv4.Width = 100;
lv4.HorizontalAlignment = HorizontalAlignment.Stretch;
lv4.VerticalAlignment = VerticalAlignment.Stretch;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv5 = new ListViewItem();
lv5.Content = "Test Content";
lv5.Width = 250;
lv5.HorizontalAlignment = HorizontalAlignment.Stretch;
lv5.VerticalAlignment = VerticalAlignment.Stretch;
// Create new StackPanel "Child" elements with alignment and width
ListViewItem lv6 = new ListViewItem();
lv6.Content = "Test Content";
lv6.Width = 250;
lv6.HorizontalAlignment = HorizontalAlignment.Stretch;
lv6.VerticalAlignment = VerticalAlignment.Stretch;
// Add "Child" elements for the new StackPanel
myStack.Children.Add(lv1);
myStack.Children.Add(lv2);
myStack.Children.Add(lv3);
myStack.Children.Add(lv4);
myStack.Children.Add(lv5);
myStack.Children.Add(lv6);
// Add the new StackPanel as a ListViewItem control
MusicQueue.Items.Insert(1, myStack);
XAML Code:
<ListView Name="MusicQueue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ListViewItem HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Orientation="Horizontal">
<ListViewHeaderItem Width="400">Filename</ListViewHeaderItem>
<ListViewHeaderItem Width="100">Format</ListViewHeaderItem>
<ListViewHeaderItem Width="100">Size</ListViewHeaderItem>
<ListViewHeaderItem Width="100">Duration</ListViewHeaderItem>
<ListViewHeaderItem Width="250">Artist</ListViewHeaderItem>
<ListViewHeaderItem Width="250">Title</ListViewHeaderItem>
</StackPanel>
</ListViewItem>
</ListView>
Of course this is probably not going to be the most efficient way to manually add an item to a ListView stacked horizontally, but it works which is most important :)
If anyone does know a quicker way to do this with less code please let me know :)
Thanks guys
You can use dataGrid in UWP.
But you also can use DataTemplate in ListView, and you can use blow code to solve the width is too small.
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment"
Value="Stretch"></Setter>
</Style>
</ListView.ItemContainerStyle>
The lib you can use is :https://github.com/MyToolkit/MyToolkit/wiki/DataGrid
And https://liftcodeplay.com/2015/10/24/datagrid-alternatives-in-uwp/
If you can spend money, you can use https://www.syncfusion.com/products/uwp/sfdatagrid

Stackpanel "breaks" and has black background when the content is side is too much

I have the follow XAML:
<ContentControl HorizontalAlignment="Left" HorizontalContentAlignment="Left" Content="{Binding TotalReviewWordBlock}" Width="465" Margin="5,10,0,5" Foreground="#FF2D2D2D" Background="White"/>
and its binded to the following property:-
public StackPanel TotalReviewWordBlock
{
get
{
StackPanel st = new StackPanel();
st.Orientation = Orientation.Horizontal;
st.Background = new SolidColorBrush(Colors.White);
Paragraph pgf = new Paragraph();
Run r = new Run();
r.Text = App.Convert("Blah ");
r.FontWeight = FontWeights.Bold;
r.Foreground = new SolidColorBrush(CommonLib.rgbFromHexString("#FF2D2D2D"));
pgf.Inlines.Add(r);
int Rating = (int)(this.userrating * 2);
string ratingReplacement;
(some more code in the property itself...)
Run run = new Run();
run.Text = " " + this.myText;
run.Foreground = new SolidColorBrush(CommonLib.rgbFromHexString("#FF2D2D2D"));
pgf.Inlines.Add(run);
RichTextBox rtb = new RichTextBox();
rtb.TextWrapping = TextWrapping.Wrap;
rtb.Width = 450;
rtb.Blocks.Add(pgf);
st.Children.Add(rtb);
st.Background = new SolidColorBrush(Colors.White);
return st;
}
}
The problem is when the text is too much(say more that a 1000 character), or the height of the stackpanel is a lot, Its background becomes black. Its as if the stackpanel breaks) I noticed this earlier but at that time it was in a listbox and had multiple items to i simply made the width of each item 480, used blank grids instead of margins and it was "covered". But this time its just one big chunk of text(in a Paragraph). Let me know if you need ay other info. Please help!!
I worked around a similar "black stackpanel" problem by splitting the text into paragraphs to form a List<String>. And then that list of strings would be the ItemsSource of a ListBox.
So instead of a very large StackPanel, I ended up with a long ListBox.
I also prevented user interaction in the ListBox and vertical scroll by using IsHitTestVisible="False" and ScrollViewer.VerticalScrollBarVisibility="Disabled"
So, the ListBoxended up as follows:
<ListBox x:Name="listBox" IsHitTestVisible="False" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Background="White">
<TextBlock TextWrapping="Wrap" Text="{Binding}"/>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in code behind:
textSplitInParagraphs = new List<String>();
// add paragraphs to the list...
listBox.ItemsSource = textSplitInParagraphs;
Don't know if it is the correct workaround, but I helped me, after some time of banging my head against the table.
Hope this helps.

Vertical scrolling in StackPanel without ScrollViewer

I am trying to fix a larger block of code written by previous colleague - it i some sort of report system, output is a table with data. My task was to freeze column headerson top when scrolling. As i am new to this, I made very simple table, to find out how datagrid works:
public MainWindow()
{
this.InitializeComponent();
var dt = new DataTable();
dt.Columns.Add("prvni");
dt.Columns.Add("druhy");
for (int i = 0; i < 100; i++)
{
var row = dt.NewRow();
row[0] = "A" + i;
row[1] = "B" + i;
dt.Rows.Add(row);
}
this.MainGrid.ItemsSource = dt.AsDataView();
}
By lots of searching, I found many topics, which recommended to get rid of ScrollViewer, as the freezed headers are in datagrid by default. This was the original part of code I modified:
var scrollViewer = new ScrollViewer()
{
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
scrollViewer.AddHandler(UIElement.MouseWheelEvent, new RoutedEventHandler(this.MouseWheelHandler), true);
var stackPanel = new StackPanel();
scrollViewer.Content = stackPanel;
...
return scrollViewer;
And in another function, it was used/called as:
var reportInfo = ((((sender as DataGrid).Parent as StackPanel).Parent as ScrollViewer).Parent as ReportOutputTabItem).Tag as ReportInfo;
Well - I removed the scrollviewer, and was returning it as StackPanel, however - now I cannot scroll at all. When I searched questions, how to add vertical scrolling to StackPanel, answers were "add ScrollViewer".
So - is there a way, how either make column headers freezed inside the ScrollViewer, or how to enable vertical scrolling in StackPanel without using scrollViewer? (and another possible solution might be to make the vertical size of StackPanel bit shorter, as there are mostly pages of results, but full page is still required to scroll a bit).
XAML part:
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl Name="MainTab" SelectionChanged="MainTabSelectionChanged" ItemTemplate="{StaticResource ClosableTabItemTemplate}"/>
<StackPanel Grid.Row="1" Name="NavigationPanel" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Height="23" Name="FirstButton" Width="40" Content="<<" Click="PageButtonClick" Opacity="0.75"/>
<Button Height="23" Name="PrevButton" Width="40" Click="PageButtonClick" Opacity="0.75" Content="<"/>
<Label Height="23" Name="PageNumberLabel" Width="70" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="1/1"/>
<Button Height="23" Name="NextButton" Width="40" Content=">" Click="PageButtonClick" Opacity="0.75"/>
<Button Height="23" Name="LastButton" Width="40" Click="PageButtonClick" Opacity="0.75" Content=">>"/>
</StackPanel>
Thanks in advance.
Well, I finally found solution to this:
Originally, the datagrid was wrapped in the StackPanel, and then in ScrollViewer. I removed the ScrollViewer, and replaces StackPanel with Grid.
Now I have both vertical scrollbars, and frozen column headers.
I removed the entire
var scrollViewer = new ScrollViewer()
{
HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
VerticalScrollBarVisibility = ScrollBarVisibility.Auto
};
scrollViewer.AddHandler(UIElement.MouseWheelEvent, new RoutedEventHandler(this.MouseWheelHandler), true);
var stackPanel = new StackPanel();
scrollViewer.Content = stackPanel;
and replaced with simple var grid = new Grid();
and all stackPanel.Children.Add(dataGrid); replaced with grid.Children.Add(dataGrid);

How to scroll content of a pivot?

I have a pivot like this on the page:
<phone:Pivot Name="pivot">
<phone:PivotItem Name="item1">
</phone:PivotItem>
</phone:Pivot>
I want to add some images to the item programmatically, so the user can scroll up-down.
When I do this, the scroll viewer doesn't work, I mean doesn't scroll down.
Image image1 = new Image();
image1.Source = ...
Image image2 = new Image();
image2.Source = ...
Image image3 = new Image();
image3.Source = ...
Grid grid2 = new Grid();
grid2.Children.Add(image1);
grid2.Children.Add(image2);
grid2.Children.Add(image3);
ScrollViewer scroll = new ScrollViewer();
scroll.Content = grid2;
item1.Content = scroll;
How can I scroll up and down content of the pivot item which is added programmatically? no matter with a ScrollViewer or without it.
Well the first thing I would do is add a listbox to your pivot
<phone:Pivot Name="pivot">
<phone:PivotItem Name="item1">
<ListBox name="ListOfStuff">
</ListBox>
</phone:PivotItem>
</phone:Pivot>
Then in your cod instead of adding the items to the grid you add them to the listbox.
ListOfStuff.Items.Add(ImageWhatever);
That should pretty much be it. Your list box will add the items and scroll as normal. Just make sure that the listbox height and width is set to the screen size or smaller. Otherwise your Listbox wont work properly.
You can even get more complicated with this and make nice designs.
Forexample:
StackPanel sp = new StackPane();
Image im1 = new Image();
TextBlock tb = new TextBlock();
//...Put your sizing and editing of objects here...
sp.orientation = System.Windows.Controls.Orientation.Horizontal;
sp.add(im1);
sp.add(tb);
ListOfStuff.Items.Add(sp);
This will cause you to have an image with a textblock next to it and it will be a single selectable item in your list.

Creating Pivot Item in Runtime, with ListBoxWithCheckBoxes

I want to create a new Pivot Item through C# during runtime, displaying a list Bx of the type ListBoxWithCheckBoxes from the toolkit, facilitating to toggle checkboxes visible or invisible in the left side.
My current version works, as far as drawing the new pivot Page, and binding items to it. But i can't get the ListBoxWithCheckBoxes to work properly.
This is from my cs file:
var itemTemplate =
#"<DataTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<StackPanel Margin=""0,0,0,17"" HorizontalAlignment=""Stretch"" Height=""78"" Orientation=""Vertical"">
<TextBlock Text=""{Binding Title}"" TextWrapping=""Wrap"" Style=""{StaticResource PhoneTextExtraLargeStyle}"" Width=""Auto""/>
<TextBlock Text=""{Binding Description}"" TextWrapping=""Wrap"" Margin=""12,-6,12,0"" Style=""{StaticResource PhoneTextSubtleStyle}"" Width=""Auto""/>
</StackPanel>
</DataTemplate>";
//Creating Pivot Item
PivotItem newPiv = new PivotItem();
newPiv.Header = "Pivot Header"; //defining a header
//Content for the Pivot Item
ListBoxWithCheckBoxes newList = new ListBoxWithCheckBoxes(); //new listbox
newList.ItemsSource = App.ViewModel.Items; //Grapping some items
newList.ItemTemplate = (DataTemplate)XamlReader.Load(itemTemplate); //using xaml template
//Adding the list to the Pivot Item
newPiv.Content = newList; //Adding list to Pivot Item
MainItemList.Items.Add(newPiv); //Adding Pivot Item
Additional info:
I suspect it to have something to do with namespaces. on the XAML, this is added:
xmlns:my="clr-namespace:System.Windows.Controls;assembly=WindowsPhoneListBoxWithCheckBoxesControl"
And a normal ListBoxWithCheckBoxes, which is not made via c# in runtime, works fine. this is made this way:
<my:ListBoxWithCheckBoxes x:Name="FancyListBox" Margin="0,0,-12,0" HorizontalAlignment="Stretch" ItemsSource="{Binding Items}" >
Register for Loaded event on MyPivotItem and set "IsInChooseState" to "true" in the event handler
private void MyPivotItem_Loaded(object sender, RoutedEventArgs e)
{
MyPivotItem pivotItem = sender as MyPivotItem;
pivotItem.myListBox.IsInChooseState = true;
}

Categories

Resources