WP7 Complex Layout - c#

I want to make a complex layout, and would like advice on the best way to go about this.
Here is the behaviour I'm looking for: Layout of some text blocks and some images, such that a tap anywhere on the layout will go to another related page to that item. I want a long list of this item in a scroll viewer.
First, I tried to make a grid, add the items in it, then add this grid in the outer grid, the main one for pressing, I made an event handler for mouse click, but a problem appeared; that when I try to scroll "on the item to view the all list" the event handler fired!, I tried the mouseButton up and down, and the same happen
Second, I'm not sure if it's an efficient way to make it.
I want a good way to design this complex layout, and of course it will be a programmatic way, and a way to recognize the item I press on.

It sounds like you're trying to create your own ListBox control. Using this will give you the scrolling functionality for free, and you can use the ListBox's SelectionChanged event to determine when an item has been clicked.
The best way to design the layout will depend on how complex it actually is. If it merely contains an image and some text, you should have no problem hand-coding that in XAML. If there's a lot more to it than that, I'd recommend looking into Microsoft's Blend tool. Whichever route you choose to produce the XAML, you will place the code in the ListBox's ItemTemplate, which determines how each item in the ListBox is displayed.
A good walkthrough of something similar to what you're doing can be found at http://weblogs.asp.net/psheriff/archive/2010/10/27/windows-phone-list-box-with-images.aspx

Related

Why UWP Flipview doesn't flip to second item?

I have a control to manage a FlipView (flipView) and I want synchronize SelectedIndex with a ListBox (subMenuList) to navigate between my contents. And because product owners have wonderfull requirements, I have another ListBox (shortcutList) in a control for the first item of the FlipView which is also binded to SelectedIndex of the FlipView.
Warning : some items of the lists are collapsed to simulate shortcuts to Flipview contents.
Those controls are perfectly synchronized together but the second item of FlipView :
Using mouse: on the first click, I can go to page 1 and when I flip back to shortcutList, I can not go to page 1 but I can go anywhere else. And then, when I flip back again to shortcutList, I can go to page 1 again and so on !
Using touch: I can tap go to page 1 as long as I want, I never reach my first page but I can go anywhere else.
I extract the specific part of my project to reproduce the use case on Github, that way everyone can understand what I mean.
I hope someone can tell me why UWP Flipview doesn't flip to second item ? And thanks to try to help me to find an issue.
The problem is that the item is already in selected state, so you cannot select it again - at least selecting it does not do anything as there is no selection changed event and hence the SelectedIndex binding doesn't propagate any changes. To prove it - the same thing happens if you jump to page 4, flip back to first page and click page 4 again.
How to solve this? I think you will have to use code. This XAML solution although almost works is quite fragile. The easiest solution would be to replace the ListBox in FlipContent0Control with three simple buttons and in their Click handlers navigate to the appropriate page. For an even better approach you should try to change the app to use MVVM design pattern.
I also commited a dirty fix on Github using directions of Martin Zikmund
How to solve this? I think you will have to use code. This XAML
solution although almost works is quite fragile. The easiest solution
would be to replace the ListBox in FlipContent0Control with three
simple buttons and in their Click handlers navigate to the appropriate
page.
and a tip from Jawahar
it is because your finger is still touching the control, so flipview
cannot animate. So I gave a small break after before navigating. By
the time user would have released the finger and it works !!!
in the following post.
So, three steps to resolve :
Replace SelectedIndex in FlipContent0Control with Tapped event on each ListBoxItem inner canvas.
Provide a event on tap to raise the target index to select in the FlipView.
Add a Task.Delay(100) in the method handler of event TargetedIndexChanged

Extremely slow performance with multiple user controls

I've put together a scheduling application similar in style to that found in outlook, however it can show the schedules of multiple people. I have written a user control, basically a Border with gradient filled background & TextBlock. One of these controls are added to a Canvas at a set location for every appointment. The trouble is, I will have multiple users, with multiple appointments and may need to display 1000 or so appointments at a time. Initially, it takes an absolute age to instantiate all of these objects, however, I can live with this.
Unfortunately, the big problem arises when I try to scroll through the appointments. I have a couple of buttons to scroll left and right and upon clicking these, the UserControls' Left position are moved left or right a certain number of pixels - it can take several seconds between clicking a button and repainting(I also tried with labels just to test, but it was the same).
I guess the real question here is how to implement an interface, showing hundreds of controls with adequate performance and if this isn't achievable, how would I approach such an UI.
One possible option is a TextBlock CustomControl. You can get the exact same style as you have in your usercontrol but with a somewhat faster loading time.
Without a good, minimal, complete code example that reliably reproduces the problem, it will be difficult if not impossible to completely understand the performance problem you are having, never mind provide a solution.
That said, from your description it sounds like you are really looking to present the user with some type of ItemsControl, such as ListBox or ListView (a specialization of ListBox). In an ItemsControl, you can specify an ItemTemplate that defines how each item in the list will appear; this is analogous to the UserControl you apparently are using now.
I believe it's likely it will work fine just with that change alone. I.e. define your per-item visual as a DataTemplate instead of a UserControl, and set the ItemTemplate property of e.g. your ListBox to that template, then just bind your collection of appointment objects to the ListBox.ItemsSource property.
Note that the ListBox class already defaults to using VirtualizingStackPanel in its ItemsPanel template. So you should have no performance problems at all with this approach if you use ListBox.
If you want to use a different ItemsControl or create a custom one, you may or may not find that you need to use a virtualizing panel object explicitly (such as the VirtualizingStackPanel that ListBox uses). With just 1000 items in the list, even a non-virtualized panel may be fine, but if not then even when not using ListBox, you can always specify it explicitly.

FocusManager.FocusedElement and MVVM

I'd like to control which button is focused in my view. User must be able to perform a job without need to use mouse. And job is going through all elements. Depending on element, some buttons will appears, some disappears.
I could do it with dependency properties. To example, if there are buttons Previous and Next, then I can provide IsPreviousFocused and IsNextFocused to set focus to them after certain event. Events can be: showing window for the first time (something should have focus already), reaching 1 element (hiding Previous button, setting IsNextFocused), reaching last element (opposite), etc.
This looks reasonable more or less.
But, if I have, to example, 10 buttons (different operations), then all of them will have to have dependency property!
So I was thinking about much easier approach: when I hide button, there will be no focus
if(FocusManager.FocusedElement == null) { ... }
If I can detect, when there are no focus, then I can try to set it to one of the buttons somehow. This way, I don't really need any complicated focus management
Question is: how to deal with FocusManager.FocusedElement in MVVM scenario? How to detect when there is no focus (when window is shown first time, when certain button is clicked and become invisible, etc)?
P.S.: I actually hate ms for making another technology without thinking fully into it; focus is very basic feature (and everybody care about it in their software), but there is no direct support for it (in xaml); looks like "oh, its too complicated, lets skip it" solution.
You could control your focus from your ViewModel by using the approach shown here:
Set focus on textbox in WPF from view model (C#)

Auto Layout Increasing Number of Controls

I am somewhat new to WPF and hopefully I'm not asking for the world here but I'm looking for advice/direction on how to go about implementing something like the following.
I'd like to have my MainWindow contain N buttons. Each Button performs the same action on a different set of data (i.e. print picture 1, print picture 2, ... , print picture N). I'd like my window to automatically layout the buttons as described below:
Note how the number of buttons increases, the layout automatically adjusts in a pleasing manner. Up to 6, and then the it provides a horizontal scroll to shuffle through the buttons.
I feel like the <Grid> control might be the way to provide this but I'm lost in how to get the automatic layout tweaks short of a lot of brute fore.
Tangentially, I see the power in Data Binding in WPF and ideally the button's info (it's display text, graphic, etc.) would be automatically binded to an observable collection so that as I insert buttons into the collection, the UI automatically updates. Conversely when each button is clicked, I'd like to have a generic handler know button 5 maps to the 5th element in my collection which has all this additional info (i.e. the file name of the picture to print).
That all sounds well and good but again I'm lost a bit in the implementation.
As Allonym said, the most customizable way would be to create a new custom Panel for this.
IMHO, it may also be possible to achieve this using a UniformGrid, and tweaking it a bit with bindings and converters. That is for the layouting.
About your second question, I think using an ItemsControl is the best way. You could pass it your new Panel (or UniformGrid) as its ItemsPanel. Also, you could then create a DataTemplate with a button inside, bind its Command property to a single command (= generic Handler), with as parameter the DataContext of the DataTemplate (= the current item of the list). This part is easier than the layouting.
Does is help?
Antoine
I think you'd have to create a custom Panel class, overriding MeasureOverride and ArrangeOverride to achieve your desired layout. Check out this (very brief) tutorial.

Best practice on repurposing button in WPF?

I have a relatively simple case where I want to repurpose a "Start" button with an "Abort" button after it is first clicked.
I'm wondering what is the best way to implement this button repurposing using XAML, hopefully declaratively rather than with a code-behind hack:
<DockPanel>
<Button x:Name="btnStart">Start</Button>
</DockPanel>
I tried the following with using two distinct Buttons and toggling the Visibility property of each but it does not reflow the layout within the DockPanel. I want the buttons to share the same layout space but mutually exclusively. This also has the problem where only the last element fills the dock panel and the first element is squished off to the left.
<DockPanel>
<Button x:Name="btnStart">Start</Button>
<Button x:Name="btnAbort" Visibility="Hidden">Abort</Button>
</DockPanel>
I prefer the two Button approach so that I can have separate Click event handlers. Please don't suggest naive solutions like dynamically adding/removing Button elements. I'd prefer a declarative approach if at all possible. Thanks!
Did you try to set the Visibility property to Collapsed instead of Hidden? If you do that, the unused button should not use any layout space.
If it's a viable option for you, you could try downloading the WPF toolkit and creating a single control with multiple states using the VisualStateManager.
Everything can be done declaratively in the XAML and switching between the States is fairly simple...especially if you're familiar at all with Silverlight development.
I don't mean to be snarky, but I wouldn't do it, unless you also change the visual state and look of the button to feel like something that would have that behavior, like an animated toggle switch or something. If the button launches a process which is slow running and you want to be able to abort it, I would think that (a) having a separate progress dialog showing the status and a cancellation option or (b) enabling that status and cancellation control in a different part of your window would be more consistent with other user interfaces. Also, accidental double clicks will immediately cancel the action, which might be odd.
When the button is clicked assign a different command to the button and change the caption. Then when it is clicked it will goto a completely different handler in the code behind.

Categories