listBox Text Will Not Wrap - silverlight

I'm trying to write a simple app that would parse a feedburner feed (in XML), extract data from the feed, scrub out some unnecessary data and then spit it out onto the screen.
I'm having difficulties wrapping the text in the listBox. I've spent the past few nights banging my head against the desk in an effort to get this to work. I've installed the Silverlight Toolkit and am trying to use WrapPanel, but it doesn't seem to want to work. The text displays fine in the listBox, I just can't seem to get the text to wrap.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ListBox x:Name="listBox1" Width="456" Height="646" ItemsSource="{Binding}" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
<Grid>
Here's the snippet of code that I'm using to add the items to the listBox:
StringReader stream = new StringReader(e.Result);
XmlReader reader = XmlReader.Create(stream);
string areaName = String.Empty;
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
if (reader.Name == "description")
{
areaName = reader.ReadElementContentAsString();
areaItem = new ListBoxItem();
areaItem.Content = areaName;
listBox1.Items.Add(areaItem);
}
}
}
Any help would be greatly appreciated!
UPDATE
I was able to get the text to populate the TextBlock by using this line:
textBlock1.Inlines.Add(areaName);
instead of this line:
listBox1.Items.Add(areaItem);
The only issue I seem to be running into now is the TextBlock not populating below the TextBlock area and not being scrollable.
UPDATE 2
Fixed this by removing the Height="x" line in the XAML. I am all set to go!

Put the text in a TextBlock and turn on wrapping?
Inside your listbox:
<TextBlock Text="{Binding}" TextWrapping="Wrap"/>

Related

WPF [VB] Bring selected ListViewItem to front and overlap other ListViewItems

I am making an explorer control in my WPF application using a Treeview and Listview. For the Listview I would like to show the contents of the selected folder using 32x32 pixel icons. To achieve this I have the following XAML which is also truncating long file/folder names within a TextBlock:
<ListView x:Name="LV_Explore"
Grid.Column="2"
BorderThickness="0"
VerticalContentAlignment="Top"
ItemsSource="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Visible"
AllowDrop="True">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="SP_ExploreItem"
Width="42">
<Image Source="{Binding LargeIcon, UpdateSourceTrigger=PropertyChanged}"
Margin="0,0,0,2" />
<TextBlock x:Name="TXT_ExploreItem"
Width="42"
Height="42"
TextOptions.TextFormattingMode="Display"
TextAlignment="Center"
TextWrapping="Wrap"
TextTrimming="WordEllipsis"
LineStackingStrategy="BlockLineHeight"
Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When selecting a ListViewItem I would like for it to overlap the items (files/folders) below rather than the current behaviour which is to increase the height of all of the ListViewItems in the current row of the WrapPanel.
To get to the ListViewItem I am using the following code in order to show all of the text in the TextBlock when an item is selected:
Private Sub LV_Explore_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles LV_Explore.SelectionChanged
If LV_Explore.SelectedItems.Count = 1 Then
Dim LVItem As ListViewItem = TryCast(Me.LV_Explore.ItemContainerGenerator.ContainerFromIndex(Me.LV_Explore.SelectedIndex), ListViewItem)
If LVItem IsNot Nothing Then
Dim BD As Border = TryCast(VisualTreeHelper.GetChild(LVItem, 0), Border)
If BD IsNot Nothing Then
Dim CP As ContentPresenter = TryCast(BD.Child, ContentPresenter)
If CP IsNot Nothing Then
Dim SP As StackPanel = TryCast(LVItem.ContentTemplate.FindName("SP_ExploreItem", CP), StackPanel)
If SP IsNot Nothing Then
Dim TB As TextBlock = TryCast(SP.FindName("TXT_ExploreItem"), TextBlock)
TB.TextTrimming = TextTrimming.None
TB.Height = Double.NaN
End If
End If
End If
End If
End If
End Sub
For reference I want to achieve similar to the behaviour of the desktop e.g: Screenshot 1: Normal state Screenshot 2: Selected state
Whereas I currently have the normal state working fine and the selected state appears like this: Screenshot 3: Listview selected state
I suspect that I may need to change from using a WrapPanel to a Canvas in the ItemsPanelTemplate of the ListView control which will then lose the behaviour of lining up and wrapping items within the Listview automatically. So I am looking for suggestions of the best approach to use here to maintain the layout and to allow me to overlap items when selected.
Thanks,
Jay
As you may realise, something in a listview item is inside a sort of a box and it isn't getting out of that. It will be truncated or clipped if you don't let it grow.
A canvas doesn't clip so that would tick one box of your requirement, you would have to write a custom panel based on a canvas or the base panel control and write your own measure/arrange code.
This is non trivial and any scrolling could make it even more complicated, but you could take a look at people's work:
eg
https://www.codeproject.com/Articles/37348/Creating-Custom-Panels-In-WPF
Alternately, you could use an adorner.
The adorner layer is on top of everything else in your window but still in the same datacontext of whatever it's associated with.
These are not so easy to work with but again you could base your code on someone else's:
http://www.nbdtech.com/Blog/archive/2010/07/12/wpf-adorners-part-4-ndash-simple-and-powerful-system-for.aspx
An adorner would probably be my first candidate, if I follow what you want correctly.
Not many people use vb nowadays and I'm afraid you're going to find pretty much every time you look at samples they are c#.

WPF Bind textbox Text to another control property [duplicate]

I have a situation where I need to create View box with one button. The xaml for this is as below: Please observe Width property of viewbox. The Width should be increased/decreased according to a slider bar(moving to right increases it, to left decreases it). As listed below I know how to do it in xaml and it works fine. But my requirement is to be able to create viewbox in code behind and assign it the properties.
<WrapPanel x:Name="_wrpImageButtons" Grid.IsSharedSizeScope="True"
ScrollViewer.CanContentScroll="True" d:LayoutOverrides="Height"
Margin="5">
<Viewbox x:Name="_ScaleButton"
Width="{Binding Value, ElementName=ZoomSlider}" Stretch="Fill">
<CustomButton:_uscVCARSImagesButton x:Name="_btnImage1"/>
</Viewbox>
</WrapPanel>
Thanks.
This should do what you want:
Viewbox x = new Viewbox();
Binding bnd = new Binding("Value") { ElementName = "ZoomSlider"};
BindingOperations.SetBinding(x, Viewbox.WidthProperty, bnd);
// ... Code to insert the Viewbox into the WrapPanel etc.
You can create the binding relatively easily in Code Behind:
var widthBinding = new Binding("Value") { ElementName = "ZoomSlider" };
_ScaleButton.SetBinding(FrameworkElement.WidthProperty, widthBinding);

How to format text in a ListBox where items are added dynamically?

I need to format the text in each textblock, which is an item of my ListBox. I have managed to make something but it doesnt look the same as if I would call the Console.WriteLine-Method.
private void addNewGameItem(string gamename, string lastChangedDate)
{
ListBoxItem lbi = new ListBoxItem();
StackPanel stpl = new StackPanel();
TextBlock tbl = new TextBlock();
tbl.Text = String.Format("{0,-100} {1,30}", gamename, lastChangedDate);
tbl.FontSize = textBlockFontsize;
stpl.Orientation = Orientation.Horizontal;
stpl.Children.Add(tbl);
lbi.Content = stpl;
savedGamesList.Items.Add(lbi);//Add the ListBoxItem to the ListBox
}
The problem is that if the gamename is longer than for example the previous one, the date will appear futher right. How can I format this, that it doesnt matter how long the gamename is, so the date-string will start on the same position, in each textblock?
This might be easier done in XAML rather than the code behind as you can more easily define the DataTemplate to be used to display your list items that way. Make your list of games an ObservableCollection and bind the ItemsSource of your list box to that. This will mean it auto-updates when you add a new item to the list.
Then you can split the string into two parts, one for the game name the other for the date:
<ListBoxItem ...>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GameName}"/>
<TextBlock Text="{Binding LastChangedDate}"
HorizontalAlignment="Right"/>
</StackPanel>
</DataTemplate>
</ListBoxItem>
Then in the ListBox style definition include the line:
HorizontalContentAlignment="Stretch"
This will make each list box item fill the entire width of the list box and (as long as the dates are formatted so that they all come out the same length) align them correctly.

Client side report generating and printing in Silverlight

I have been working on a project that needs to produce a simple report containing a header, a table with simple grouping and a footer. this report needs a print functionality and it can be more than one page.
I found it really difficult to create this report using DataGrid since I can't generate and print more than one page PrintDocument .
So far I tried to use iframe (using HTMLPlaceHolder by Telerik) with html report which I generate using silverlight code behind but javascript printing function prints the entire silverlight page.
I have telerik and I use it for advance reports but I don't want to use telerik report for this specific report since the report is generating on the server(I don't want to pass any value back to server at all for this report).
Is there any way to generate such a report in client side with printing functionality.
I am open to all suggestion as long as it's not too expensive (up to $100)
Let me know if you need more detail.
You might want to use PrintDocument class in Silverlight. The usage is like..
in XAML file create List as
<ScrollViewer Height="300" VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="printSurface">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
Height="25">
<TextBlock Width="100"
Text="{Binding Name}" />
<TextBlock Width="75"
Text="{Binding Genre.Name}" />
<TextBlock Width="50"
Text="{Binding Price, StringFormat=c}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
and Code behind looks like
void printButton_Click(object sender, RoutedEventArgs e)
{
PrintDocument doc = new PrintDocument();
doc.PrintPage += new EventHandler<PrintPageEventArgs>(doc_PrintPage);
doc.Print("Page title");
}
void doc_PrintPage(object sender, PrintPageEventArgs e)
{
// Stretch to the size of the printed page
printSurface.Width = e.PrintableArea.Width;
printSurface.Height = e.PrintableArea.Height;
// Assign the XAML element to be printed
e.PageVisual = printSurface;
// Specify whether to call again for another page
e.HasMorePages = false;
}

Silverlight combobox performance issue

I'm facing a performance issue with a crowded combobox (5000 items). Rendering of the drop down list is really slow (as if it was computing all items before showing any).
Do you have any trick to make this dropdown display lazy?
Xaml code:
<Grid x:Name="LayoutRoot">
<StackPanel Orientation="Horizontal" Width="200" Height="20">
<TextBlock>Test Combo </TextBlock>
<ComboBox x:Name="fooCombo" Margin="5,0,0,0"></ComboBox>
</StackPanel>
</Grid>
code behind:
public MainPage()
{
InitializeComponent();
List<string> li = new List<string>();
int Max = 5000;
for (int i = 0; i < Max; ++i)
li.Add("Item - " + i);
fooCombo.ItemsSource = li;
}
Well, there seems to be a bug in the Combobox UI virtualization, so an autocompletebox should be the way to go.
If you want an actual ComboBox (and not an AutoCompleteBox) that did this you could replace the ItemsTemplate with a VirtualizingStackPanel. In your example this would look like:
<ComboBox x:Name="fooCombo" Margin="5,0,0,0">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel></VirtualizingStackPanel>
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
As a guide though, I'd probably review your usage scenario to see whether or not a ComboBox is the correct control for you - since 5000 items seems like a mighty lot for a drop down list.
By the way, the slowness is expected behavior in Silverlight and not a bug.
Use the AutoCompleteBox instead, adjust the number of characters that need to be entered before a drop down list will be filled to limit how many drop down items are needed at any one time.

Resources