|
Given the following xaml:
<ListBox
Name="listBox"
BorderThickness="0"
SelectionMode="Extended"
KeyUp="listBox_KeyUp"
SelectionChanged="listBox_SelectionChanged"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Name="wrapPanel"
MinHeight="17"
Width="444"
IsItemsHost="True"
Orientation="Horizontal"
HorizontalAlignment="Left"
>
</WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
How do I dynamically size the width of the WrapPanel? The name of the WrapPanel ("wrapPanel") does not seem to be available from code behind. Also, the following code returns null:
Object o = listBox.FindName("wrapPanel");
The following line throws a "file not found" exception:
Object o = listBox.ItemsPanel.FindName("wrapPanel", listBox);
What I want to do is keep the width of the WrapPanel in step with changes to the width of the ListBox. As you can see, right now it's hard-coded as 444, which is the width of the ListBox when the dialog first comes up, but as the user drags the left or right border of the containing resizable window, the ListBox width changes but the WrapPanel is locked at 444. Somehow I need to get ahold of the WrapPanel object.
|
|
|
|
|
You can bind the width (or height if wrapping the other way) to the corresponding property in the ScrollContentPresenter
<WrapPanel
Name="wrapPanel"
MinHeight="17"
Width="{Binding ActualWidth,
RelativeSource={RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
IsItemsHost="True"
Orientation="Horizontal"
HorizontalAlignment="Left"
>
|
|
|
|
|
Thanks for your suggestion. It's certainly better than I originally had, and I don't quite understand what ScrollContentPresenter has to do with it. But your suggestion only works if I make the containing dialog wider. As I stretch the dialog horizontally, the WrapPanel's width does increase with the width of the dialog and the height of the WrapPanel automatically decreases, but if I make the width of the dialog smaller, the WrapPanel's width and height stays where it was at its widest value and ListBoxItems get truncated to the right within the WrapPanel. What I expected to happen as the dialog width got smaller was the height of the WrapPanel to increase and its width to decrease to accommodate all the ListBoxItems so that they all always remain fully visible.
Perhaps it would help you to find the solution to the remaining problem if you saw my entire XAML file. As you can see, it's actually a UserControl that is used multiple times within a containing dialog.
<UserControl x:Class="CustomControls.HorizontalListBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="UserControl_Loaded"
>
<Border
BorderThickness="2"
BorderBrush="DarkBlue"
CornerRadius="3"
>
<ScrollViewer
Name="scrollViewer"
MaxHeight="68"
VerticalAlignment="Top"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Hidden"
>
<ListBox
Name="listBox"
BorderThickness="0"
SelectionMode="Extended"
KeyUp="listBox_KeyUp"
SelectionChanged="listBox_SelectionChanged"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Name="wrapPanel"
MinHeight="17"
Width="{Binding ActualWidth,
RelativeSource=
{RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
IsItemsHost="True"
Orientation="Horizontal"
HorizontalAlignment="Left"
>
</WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</ScrollViewer>
</Border>
</UserControl>
|
|
|
|
|
I think all you need to set is:
ListBox.HorizontalContentAlignment=Stretch
If that doesn't work then a control containing the UserControl may need that value set as well.
|
|
|
|
|
hb52134214 wrote: ListBox.HorizontalContentAlignment=Stretch
Unfortunately, that doesn't work, and the control containing the UserControl is a Grid, which doesn't take HorizontalContentAlignment. I wonder if there's something missing in the WrapPanel XAML:
<WrapPanel
Name="wrapPanel"
MinHeight="17"
Width="{Binding ActualWidth,
RelativeSource=
{RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
IsItemsHost="True"
Orientation="Horizontal"
HorizontalAlignment="Left"
>
</WrapPanel>
|
|
|
|
|
Dropping your code directly into a window with a few changes:
<ListBox Name="listBox"
BorderThickness="0"
-> HorizontalAlignment="Stretch"
-> HorizontalContentAlignment="Stretch"
-> ScrollViewer.HorizontalScrollBarVisibility="Disabled"
SelectionMode="Extended">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Name="wrapPanel"
MinHeight="17"
-> HorizontalAlignment="Stretch"
Background="Blue"
IsItemsHost="True"
Orientation="Horizontal"
></WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
Does what I think you're trying to achieve.
If the list box is inside a grid, a grid will default to resize with its container, but the columns may not? In the grid set the column width to '*':
<Grid.COlumndefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
If you have more than one column, do the rest have their widths set to 'auto'?
|
|
|
|
|
Interesting that it's working for you outside of a Grid. You don't even have the ActualWidth binding in the WrapPanel. I took out my binding and added in the WrapPanel HorizontalAlignment to Stretch. It definitely needs the binding. Without that, the ListBoxItems don't even try to wrap properly.
hb52134214 wrote: If the list box is inside a grid, a grid will default to resize with its container, but the columns may not? In the grid set the column width to '*':
The Grid itself does resize with its container (another Grid, which itself is the outer element of the Window). The Grid resizing is working fine, as is the ListBox itself in the third column of its Grid container. The problem is the ListBox.ItemsPanel is not.
I need the first two columns to be hardcoded because they have to line up with columns in another grid beneath the one the UserControl is in. The third column does use *:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"></ColumnDefinition>
<ColumnDefinition Width="65"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
So still only a partial solution. If somehow I could get hold of the WrapPanel object, I'd be fat city, because I could just trigger on the width of the dialog. That was my original question: how do I get hold of the WrapPanel, since trying to use its Name ("wrapPanel") doesn't work, probably because it's in an ItemsPanelTemplate. The original reply suggested the ActualWidth binding, but that only half works: expanding the width of the containing window works, but not contracting it. Since I'm saving the width of the window, contracting its width and then restarting it fixes everything, but customers would roll their eyes at that work-around.
|
|
|
|
|
Reviewing the posts, the list box is nested as follows:
<window>
<grid>
<grid>
<userControl>
<ScrollViewer>
<listbox>
Why do you have the list box in the scroll viewer? The list box already includes one.
Is it included to enable setting the VerticalScrollBarVisibility="Auto" and HorizontalScrollBarVisibilty="Hidden"? If so, they can be set in the list box:
<ListBox
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibilty="Hidden"/>
|
|
|
|
|
hb52134214 wrote: Why do you have the list box in the scroll viewer?
Because I was under the mistaken impression that the ListBox did not have a built-in scroll viewer. But those properties you say I can set
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibilty="Hidden"
don't exist and are not needed anyhow. Removing the scrollviewer completely solved my problem. The XAML now looks like this:
<UserControl x:Class="CustomControls.EmailAddressesListBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="UserControl_Loaded"
>
<Border
BorderThickness="2"
BorderBrush="DarkBlue"
CornerRadius="3"
>
<ListBox
MaxHeight="68"
BorderThickness="0"
SelectionMode="Extended"
KeyUp="listBox_KeyUp"
SelectionChanged="listBox_SelectionChanged"
>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
MinHeight="17"
Width="{Binding ActualWidth,
RelativeSource=
{RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
Orientation="Horizontal"
>
</WrapPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Border>
</UserControl>
|
|
|
|
|
Thanks
This did the magic for me
|
|
|
|
|
The ScrollContentPresenter comes from the default template of ListBox (or more accurately, the ScrollViewer that a ListBox creates). The ScrollContentPresenter is the region inside a ScrollViewer that is not used by the scroll bars. When I first replied, I was rather hasty with the copy and paste of the WrapPanel. You really do not need several of those properties set.
<WrapPanel
Name="wrapPanel"
MinHeight="17"
Width="{Binding ActualWidth,
RelativeSource=
{RelativeSource AncestorType={x:Type ScrollContentPresenter}}}"
IsItemsHost="True"
Orientation="Horizontal"
HorizontalAlignment="Left"
/>
The Name is not useful because you won't be able to access the panel by name anyway. The IsItemsHost is ignored because it is already in the ItemsPanelTemplate. The default HorizontalAlignment is always what you end up wanting.
There are several possible reasons that come to mind for why the control is not sizing back down. One is that the when you are using the UserControl elsewhere, the sizing is not bound correctly and is thus only growing. Another option is that some other control in the the grid where you use this control is not sizing back down. If you are doing manual sizing in the code-behind somewhere else in the application where this control is used, that could be preventing the control from sizing back down. (In general, you should not have explicit sizes, except on windows, or mess with sizes in the code-behind in WPF. The automatic sizing should be able to handle most cases.) Some XAML from where this control is used may show the problem.
As a aside for design philosophy, does this UserControl do something special other than select horizontal wrap panel by default? If not, you would probably be better off defining a Style and applying it to any ListBox that you want to have this look and items panel. If you do leave this as a UserControl, you should take out the explicit ScrollViewer since the ListBox will create a ScrollViewer internally if needed.
|
|
|
|
|
The most important thing you wrote in your post is the following:
Gideon Engelberth wrote: If you do leave this as a UserControl, you should take out the explicit ScrollViewer since the ListBox will create a ScrollViewer internally if needed.
Removing ScrollViewer solved all my problems! It now wraps properly on the fly whether I make the dialog wider or narrower. Thank you very much for pointing this out. I thought only TextBox and RichTextBox had built-in scrollbars.
But let me comment on your other suggestion that I define a style instead of creating a UserControl. I did not embark on this decision lightly! The code behind in the UserControl is about 600 lines of C#. There is all kinds of data analysis required to style the individual ListBoxItems: different colors, different font styles, different font weights, underlining, all determined by the semantics of what the user types in. The original content of each ListBoxItem starts out as a TextBox that the user can type into. When he presses the Enter key, the code behind changes the ListBoxItem.Content to either a heavily styled TextBlock or a horizontal StackPanel with graphics and a styled TextBlock. The graphics in the StackPanel indicates to the user what will happen when he double-clicks the containing ListBoxItem. There are also several custom dependency properties and routed events that are defined in the UserControl. I don't think all this could be done just with styles.
I removed the Name (residual when I was trying various incarnations of FindName that did not work), IsItemsHost, and HorizontalAlignment.
|
|
|
|
|
That's a pretty decent reason to have a custom control. The only other approach I would suggest as a possibility is to wrap the coloring, styling, TextBox to StackPanel stuff into a UserControl of its and use that control as the ItemTemplate for a normal ListBox. Depending on how much of that 600 lines is needed to determine which TextBox is being entered in and which item to update, there could be some big savings by wrapping that into its own control.
|
|
|
|
|
I'm trying to debug one of my Silverlight 3 applications.
I go into debug mode and launch the page, but my breakpoints say they will never be hit because no symbols have been loaded. This just started! Has anyone seen this and how do I fix it???
My project is in debug mode, debugging is turned on, it is attached to the local test environment. Everything checks out except for the fact that I cannot stop my code and it appears nothing is executing correctly. (expected web service not getting called which I am able to properly place in debug mode)
Help!
|
|
|
|
|
I've always just needed to kill the app, flush
the browser cache to force reloading a new XAP,
and run it again.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Hi Mark,
I flushed my cache (I think...you know how they changed everything around in Windows 7) I searched and deleted all of my xap files, and I still get the 'symbols not loaded' message after loading the page object!!
Any other suggestions?
Thanks,
Michael
|
|
|
|
|
Go to the properties of your web project, select web on the left and then scroll down to the end of the page.
Make sure that the ASP.Net and Silverlight Debuggers are checked.
|
|
|
|
|
It seems that when I refreshed my project from SVN, it did not save the debug settings. It reset my debug switches, which I was not expecting.
Thanks to you and Mark....I'm back in debug state!!!
|
|
|
|
|
Michael Eber wrote: I'm back in debug state
Great.
Me, I'm dishonest. And a dishonest man you can always trust to be dishonest. Honestly. It's the honest ones you want to watch out for...
|
|
|
|
|
|
can anybody tell me is isolated storage in silverlight is permanent ?
because once i restart my system all the files which i created in my isolated storage are deleted
and also if i close my visual studio and reopen it than it also removes all the
previously created files .
any help ?
regards.
Tauseef A Khan
MCP Dotnet framework 2.0.
|
|
|
|
|
Tauseef A wrote: is isolated storage in silverlight is permanent ?
Permanent until a user or an application deletes something.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Tauseef A wrote: because once i restart my system all the files which i created in my isolated storage are deleted
and also if i close my visual studio and reopen it than it also removes all the
previously created files
There are two types of isolated storage - "Application" and "Site". Both are scoped by the user..since the files are stored under the user's AppData on Windows. These are permanent and not cleared even when you clear the browser's cache or restarting the system.
Now...bring me that horizon. And really bad eggs...Drink up me hearties, YO HO!
|
|
|
|
|
|
Make sure you call the update method or the changes aren't committed
|
|
|
|
|
Hi,
Do you know any ListView styles sample in XAML code ?
Thanks.
|
|
|
|
|