How to scroll content of a pivot? - c#

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.

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

Dynamic grid within a scrollviewer

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

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.

Is there a code-behind equivalent for TextBlock ScrollViewer.CanContentScroll="True" for DataGridTemplateColumn?

For a TextBlock in XAML, you can do the following inside a DataTemplate:
<TextBlock Text="myTextBlock Text" VerticalAlignment="Center" Margin="0,0,5,0"
ScrollViewer.CanContentScroll="True" ScrollViewer.HorizontalScrollBarVisibility="Visible"/>
But when I try to set ScrollViewer.HorizonalScrollBarVisibility, it doesn't seem to do anything.
DataTemplate textBlockTemplate = new DataTemplate();
FrameworkElementFactory textBlockElement = new FrameworkElementFactory(typeof(TextBlock));
Binding c1Binding = new Binding("myBindingValue") { Mode = BindingMode.TwoWay, UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged };
textBlockElement.SetBinding(TextBlock.TextProperty, c1Binding);
textBlockElement.SetValue(TextBlock.TextWrappingProperty, TextWrapping.Wrap);
textBlockElement.SetValue(TextBlock.HeightProperty, System.Convert.ToDouble(23));
textBlockElement.SetValue(ScrollViewer.CanContentScrollProperty, true);
textBlockElement.SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, ScrollBarVisibility.Visible);
textBlockTemplate.VisualTree = textBlockElement;
templateColumn.CellTemplate = textBlockTemplate;
myDataGrid.Columns.Add(templateColumn);
I am trying to make a DataGrid Column that has a TextBlock that shows one line of text, but allows you to scroll up/down to see the rest of the textblock.
TextBlock doesn't have a ScrollViewer contained in it to set scrolling behavior on. You need to wrap it in a ScrollViewer on which you can set whatever you want. Contrast this to a ListBox, which does contain a ScrollViewer in its ControlTemplate so can take advantage of the attached properties.

adding an image to a label in wpf?

I am currently developing an application in C# using WPF. What I need to be able to do is on a label make their be an image to the left of the text of the label a small image of an X or a small image of a tick depending on the circumstances. I have got the images included in the project in a folder named images.
How can I assign the images to be placed on the left of the label programatically in the code and not using the XAML code.
You can either group this inside a grid:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="{Binding ImageSourceProperty}" />
<Label Grid.Column="1" Content="{Binding LabelTextProperty}" />
</Grid>
Or, since the label is a content control, you can simply put the image control inside a label control:
<Label>
<Image Source="{Binding ImageSourceProperty}" />
My Text
</Label>
Once you know how the xaml should look like, it is very easy to create the same elements via code.
Since you want this in code behind and not within XAML I would suggest ditching the Label and using a StackPanel coupled with an Image and TextBlock as seen below where MyGrid could be any container...
<Grid Name="MyGrid"/>
...then in your code behind...
StackPanel myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Horizontal;
Image myImage = new Image();
BitmapImage myImageSource = new BitmapImage();
myImageSource.BeginInit();
myImageSource.UriSource = new Uri("Images/MyImage.png");
myImageSource.EndInit();
myImage.Source = myImageSource;
TextBlock myTextBlock = new TextBlock();
myTextBlock.Text = "This is my image";
myStackPanel.Children.Add(myImage);
myStackPanel.Children.Add(myTextBlock);
MyGrid.Children.Add(myStackPanel);
I don't agree with the two other answers here. There is no need for a grid to be added to wrap the content. The stackpanel is sufficient.
In the xaml add a stackpanel to where you need the content to be.
<StackPanel Name="myStack" Orientation="Horizontal"></StackPanel>
Then in the code behind, like in a button handler or when the window loads add this
Image coolPic = new Image() {
Name="pic",
Source = new BitmapImage(new Uri("pack://application:,,,/images/cool.png")),
Stretch = Stretch.None // this preserves the original size, fill would fill
};
TextBlock text = new TextBlock() {
Name = "myText",
Text = "This is my cool Pic"
};
myStack.Children.Add(coolPic); // adding the pic first places it on the left
myStack.Children.Add(text); // the text would show up to the right
You can swap the location of the image and the text by adding the text first then the image.
If you don't see the image ensure the image's build action is set to resource in the properties window of the image.
In order for the code to be more useful and or more dynamic you would need a way to change either the text or the image.
So lets say you did want to change those and you go ahead and do a
((TextBlock)FindName("myText")).Text = "my other cool pic";
You would expect the text to be changed but what happens?
Object reference not set to an instance of an object.
Drats but I gave it a name. You would need to add
// register the new control
RegisterName(text.Name, text);
So that you can access the textblock later. This is needed because you added the control to the framework after it was built and displayed. So the final code looks like this after registering the image too
Image coolPic = new Image() {
Name="pic",
Source = new BitmapImage(new Uri("pack://application:,,,/images/cool.png")),
Stretch = Stretch.None // this preserves the original size, fill would fill
};
// register the new control
RegisterName(coolPic.Name, coolPic);
TextBlock text = new TextBlock() {
Name = "myText",
Text = "This is my cool Pic"
};
// register the new control
RegisterName(text.Name, text);
myStack.Children.Add(coolPic);
myStack.Children.Add(text);

Categories

Resources