Creating a Scrollable StackPanel Control - c#

How would I create a control like the example at this site as a User Control?
So, instead of doing this:
<ScrollViewer>
<StackPanel>
<!– Content –>
</StackPanel>
</ScrollViewer>
I could do this:
<ScrollableStackPanel>
<!– Content –>
</ScrollableStackPanel>

Unfortunately, there is no way to do that as a UserControl in WPF. You would need to make a custom control (instead of a user control) based on ItemsControl. It could handle this correctly.
That being said, I don't see much point in this. It's very easy to just put your StackPanel within a ScrollViewer - why reinvent the wheel?

It looks like you just need to use a ListBox. You can override the ItemContainterStyle and ListBox.Style to get rid of all the Selected behaviours and backgrounds if you want. Because a ListBox has StackPanel and ScrollViewer in it by default.

Related

WPF ListView virtualization in a ScrollViewer

I have a requirement which is to display a user information at top of the page and a ListView of images will follow it, and I've wrote following code (it's a pseudocode but I think it's enough to explain what I've done):
<ScrollViewer>
<StackPanel>
<Grid>
<!-- User Information Part -->
</Grid>
<ListView>
<!-- Images Part, This is a custom virtualized ListView, it's ItemsPanel is a custom VirtualizingWrapPanel -->
</ListView>
</StackPanel>
</ScrollViewer>
But in this scenario, the VirtualizingWrapPanel (by which has been tested on another individual ListView without an explicit ScrollViewer declaration and it works correctly) and the virtualization of ListView won't work because the desired height of ScrollViewer is positive infinity and all the items in the ListView will be expanded and rendered, I wonder whether there is a way that can make the ListView in ScrollViewer being virtualizable? Thanks
You can't virtualize a list that has all elements being rendered (because of the StackPanel),
A workaround that will work for you: you need a single ListView. With the first row customized to display the User Information Part, and all other rows displaying images.

How to virtualize data in simple stackpanel in Windows Phone application

I have created a list with ScrollViewer and stackpanel. I am adding user control to this stackpanel from codebehind.
I want to virtualize data that I can improve the performance of my application.
How can i achieve this?
I cann't use Listbox because I am adding user control as DataItems and each user control have a different width and height.. Please suggest how to implement that
Code:
XAML
<ScrollViewer>
<StackPanel x:Name="stckPnlComponentsLst" Visibility="{Binding IsBusy, Converter={StaticResource BooleanToVisibilityInvertedConverter}}" Orientation="Vertical">
</StackPanel>
</ScrollViewer>
C#
for (int count = 0; count < countItems; count++)
{
stckPnlComponentsLst.Children.Add(new ChannelNewsLstControl(ViewModel.ComponentData[count], false, false));
}
I don't see any case in which using a StackPanel inside a ScrollViewer is a good idea.
You should not do that.
There are 2 controls to do what you want, ListBox and ListView.
If you really want to stick with a stackpanel inside a ScrollViewer, just replace your StackPanel, by a VirtualizingStackPanel. But again, you should NOT be doing that.
Use a ListBox instead. Check the sample here. For example, define ListBox in a xaml
<ListBox x:Name="MyList">
and then in codebehind
var MyListData = new List<ChannelNewsLstControl>();
MyListData.Add(new ChannelNewsLstControl {name = "MyFirstChannelName});
MyList.ItemsSource=MyListData;
If you have really lots of items, i'd recommend to use Telerik's DataBoundListBox as it is much faster than a normal ListBox (at least, for wp7) and supports virtualization and async loading. Sample would be pretty the same, as component is inherited ListBox and adding own features mentioned before.
EDIT: final answer:
Try to put a grid inside of your ItemTemplate and set its RowDefinition.Height = "Auto". See some details here

Change a section of a window upon click event

I have a treeview at the left side of the screen, and when I click on any of the TreeViewItem, I want the right side of the screen to change accordingly.
For example, clicking on 'Project' would display on the right half of the screen, a label for project name along with the project name in a text box, and a similar label-textbox pair for some other fields. Clicking on a sub-option of 'Project' such as 'Task 1' should change the right half of the screen such that instead of labels and textboxes for project name and details, it should now be for task name/details. Atm, I only care about label-textbox pairs but in the future I'll need some more sophisticated options, maybe buttons and tables.
What I thought of was to have a grid premade for each option, when I clicked on 'Project' there would be a grid which displays all the info for a Project. And when I then clicked on 'Task 1', the Project grid should be hidden and the Task grid should be displayed with the fields filled out.
Is this possible? What should I be using to create templates that I can then choose from?
Firoz already mentioned the important bit. A rough guess is that you're not using MVVM pattern, so to minimize the adaption effort, you could add a Content Control to your window and set the content of this control whenever a selection is made. You can put any User Control in there.
Using MVVM would mean you bind that Content Control to a property on your ViewModel (of type UIElement or UserControl) and set an instance whenever a bound selected values changes. Speaking of selected Value, I think the default TreeView is not really Binding-friendly, so you might end up with behaviours that do the binding for you.
What you are asking to do is quite easy and possible, but I don't think you are thinking quite big enough.
As your project grows and the number of different things that you want to show expands, then you are going to need to show and hide more and more controls. This is quite quickly going to get unmanageable. Instead think about some other controls deal with this, in some ways you are doing something very like a tabbed dialog, just with a hierarchical set of tabs.
A tabbed dialog has a panel and a set of tabs, when you click on each tab, the content of the panel changes. In fact you can create UserControls one for each specialised set of UI that you want to display, e.g. you could have a ProjectControl that displays all of your project textboxes, labels, buttons etc.
In addition WPF has this neat feature called DataTemplates, these define how a type of data should look when it is displayed. So if you where to have a
public class MyProject
{
public string Name {get;set;}
}
Then you could define
<DataTemplate DataType="{x:Type MyProject}>
<TextBox Text="{Binding Name}"/>
</DataTemplate>
And WPF will automatically convert the data into to its visual form if you set it as the content of the tab panel.
However this type of displaying content in a panel is not the only WPF control that does this. There is also something called a NavigationFrame, which also can be used wrapped into a Window as a NavigationWindow. This control provides you ways to navigate to the next Page to display. Pages can be just like the UserControls in a tabbed dialog, but can also be URIs, enabling you to link in content from the web if you wish. In addition you can call NavigateTo from other controls enabling you build much more usable interfaces.
I worked through the process of building a full windows control panel style interface in
http://alski.net/post/2012/01/11/WPF-Wizards.aspx
and http://alski.net/post/2012/01/13/WPF-Wizards-part-2-Glass.aspx
I've added later VS2012 style glows in
http://alski.net/post/2013/09/14/WPF-Re-creating-VS2012Office-2013-window-glow.aspx
And then released the entire source code as open source at
http://winchrome.codeplex.com/
This comes with support for embedding Navigation panels with
<WinChrome:SearchableNavigationWindow
x:Class="WinChrome.Win7Demo.MainWindow"
...
xmlns:WinChrome="clr-namespace:WinChrome;assembly=WinChrome"
Style="{StaticResource Win7NavigationWindow}">
<WinChrome:SearchableNavigationWindow.Navigation>
<view:Navigation x:Name="navigationTree"/>
</WinChrome:SearchableNavigationWindow.Navigation>
(Full source code)
Where the navigation window is embedded as, but can also be a TreeView.
<UserControl x:Class="WinChrome.View.Navigation" ...>
<ScrollViewer HorizontalScrollBarVisibility="Disabled" Padding="12,0"
VerticalScrollBarVisibility="Auto" >
<StackPanel>
<Button
Margin="0,12,0,0" Style="{StaticResource LinkNavigatorButtonStyle}"
Content="Home"
Command="{Binding
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Win7Demo:MainWindow}, AncestorLevel=1},
Path=GoHomeCommand}" />
</StackPanel>
</ScrollViewer>
(Full source code)

How do I make clickable text

I have been trying to create buttons on Windows Phone 8, which don't look like buttons, but just look like text, however, I haven't been able to find this question answered anywhere else. I am trying to create something like what Microsoft have used below for the camera roll, albums and date buttons below. Is anybody able to explain how I can do this, or maybe link me to a tutorial or something that I may have missed while searching? Thank you.
Windows phone uses XAML code to create UIElements. Very similar to WPF, you can use almost any UIElement as a button. This is because each element has a large amount of events that can be tracked. Think of it as a layered cake. If you have a textblock inside of a listbox inside of a grid, similar to what you see above. Then when someone clicks on the textblock it will try to handle the event. If it isn't set to handle it then the listbox tries. If the listbox cant then the grid tries and so on. What you are looking for is the tap event in the textblock. Google textblock tap event.
<Grid x:Name="LayoutRoot" Background="Transparent">
<ListBox>
<StackPanel>
<TextBlock Tap="title_Tap_1" Name="title">title</TextBlock>
private void title_Tap_1(object sender, System.Windows.Input.GestureEventArgs e)
{
//Your code here
}
I tend to use a ListBoxItem to wrap a TextBlock. It allows you to use the TiltEffect from the wpToolkit to show interaction and also exposes a Tap event for the ListBoxItem
<ListBoxItem toolkit:TiltEffect.IsTiltEnabled="True" Tap="On_Tap">
<TextBlock>Hello World</TextBlock>
</ListBoxItem>
I don't know for Windows Phone 8 because I haven't written any app yet. I think that this is like Windows Phone 7 , 7.1 that I used to write code. This control that you see is a ListBox and inside there are ListBoxItems. ListBoxItem can be anything (it can be used as a container to insert anything inside it.). Hope it helps.
The easiest way is to use HyperlinkButton instead of classic Button. In that print screen I doubt there's a list for only like... 3 buttons (hyperlinkbuttons).
Controls in the xaml world are look-less: use a button in your ItemTemplate and turn the border off. Then you can use the command property of the button for binding to your VM, or if you are not using MVVM use the Click event of the button and handle it in the code behind.

How to create a "more details" control

Can you recommend control or maybe an easy way to do this in WPF application. What I want is control that will collapse and expand itself on button press. It will be great if it looks like Win7 default one.
Here you are - Expander. Use IsExpanded property to change Expander's content visibility from code, or use built-in toggle button to change it interactively.
The read area is a header of Expander, the green area is a content of Expander.
To achieve the same behavior, you also need to set Expander.ExpandDirection property to Up value.
If you want to animate expanding, you'll need to add a trigger on IsExpanded = true an animation storyboard.
There is nothing in the framework itself to do precisely that, but it's easy to bend it your way.
You can use the Reveal control (from Bag of Tricks), and plant the toggle button that triggers the animation in the bottom bar.
Just copy/paste the control in your solution, then use it like this:
<local:Revealer IsExpanded="{Binding DetailsShown}">
<TextBlock Text="{Binding DetailInfoOne}" />
...
</local:Revealer>
And then at another location (bottom of your window?)
<ToggleButton Content="More details" IsChecked="{Binding DetailsShown}" />
Putting the arrow button and changing text to "Fewer details" is left as an exercise for the reader ;)
How about something like setting all your detailed info in a stack panel and put it to Visibility of Collapsed. When you push the button, set it to visible. The summary info is then set to collapsed and vice-versa.
The form will have to have a size set to Auto so that it will change depending of the content.
Hope that helps.

Categories