I have a view with a lot of labels and buttons which are created on code because in IB is too complicated. This works ok.
In IB I also created an input view which I want to appear from the bottom by the tap on a button. Very much like a keyboard if you will. Because this input view is strigth forward, it has been created on IB and it contains sliders, labels, etc. I haven't added it as a subview of self.view on IB.
By the tap of the button, I set up all the constrains for the input view: I set the width, I set it on the bottom of the self.view with vertical size, then I remove this constraint, I add the actual heigth and then I animate with [self.view layoutIfNeeded].
The thing is that the input view itsef animates correctly, but its subviews not so much. They kind of appear at once.
I have tried adding a input view programmatically, with only one switch. It animates quite nicely.
I'm guessing that there is a problem with the constrains between the controls and their superView. But I'm not sure about it, because although they do not animate correctly, they are on the correct place and witht the correct proportions. I guess I'm missing something here. Maybe it's not a good idea to mix IB set controls and views and programmatically modifying them?
Does somebody have any experience with that?
Thanks in advance,
I suggest you post to Apple's dev boards on this subject. I've seen several posts there recently. The Apple Engineers who replied said that with Autolayout, you basically give autolayout ownership of your view's center, size, and sometimes, transform.
To animate views that use autolayout, you should apparently use UIView block animation and animate the constraint settings on the views. The system will then animate the changes you make.
Not sure about adding new views programmatically and having them animate into place however.
Related
I need to develop a simple WPF application. In the UI window, There are Labels and Text Blocks towards the left and Buttons towards the right.
Figure 1
Based on a config setting (whether the user is left-handed or right-handed) I need to switch the controls, Buttons towards the left and Labels and Text Blocks towards the right.
Figure 2
Can you please recommend a good way to address this requirement?
Depends what the scope of the app is likely to be.
2 alternatives:
1)
I think it likely as an app grows that there will be more than just buttons.
I would probably build a usercontrol which encapsulates this behaviour for a label and control. The usercontrol uses a static to decide where the textblocks are positioned but would look something like the row edit control in this:
https://gallery.technet.microsoft.com/WPF-Entity-Framework-MVVM-78cdc204
Which is a usercontrol has a contentpresenter in it so you can put any control you like ( such as a button ) "in" it and set a dependency property for the label.
2)
Define 2 contentcontrol templates similar to the one used in this:
https://social.technet.microsoft.com/wiki/contents/articles/28597.aspx
Put them in separate resource dictionaries and give them the same key.
Merge into application.current.resources the appropriate resource dictionary and hence style.
Seeing as this is an app setting, this is presumably a start up thing. People don't just change their "handedness" dynamically. So you could probably use these as staticresource. If they're realistically going to change at run time then I think this would be a bit more involved because you'd need to force re render of a view.
2 Templates are probably the right and stylish solution here as #RajN said.
Also you can define a grid with 2 columns and switch the property 'Grid.Column' of each controls accordingly
Maybe not the best way, but I managed to achieve this using a grid as per your suggestions. Thank you all for your valuable feedback.
I switched the columns and changed the widths accordingly.
if (AppSettings.IsLeft)
{
parentGrid.ColumnDefinitions[0].Width = new GridLength(400, GridUnitType.Pixel);
parentGrid.ColumnDefinitions[1].Width = new GridLength(1, GridUnitType.Star);
Grid.SetColumn(buttonGrid,0);
Grid.SetRow(buttonGrid,0);
Grid.SetColumn(contentGrid,1);
Grid.SetRow(contentGrid,0);
}
I'm looking to create a custom control which represents a hand.
This at needs to be bound to a datasource, then if a value/index value is present in the datasource which is representing a particular finger, the finger in question should appear green.
Can anyone point me in the right direction to start of with such control?
Basically I'm creating an app which records which fingers people where their rings and how many.
So graphics on each finger will show Green plus a number showing how many.
Rough Hand Design for User Control
Any help or direction will be mostly appreciative.
I'd recommend a usercontrol rather than custom control for this. As I think that link Clemens posted says, unless you really are going to switch out the template of the control then you don't need to do a custom control - which would be harder than a usercontrol.
This will have at least one dependency property you're going to bind your collection to. Make that an ObservableCollection. You can then pass say 0,1,0,2,0. If people change the rings they wear super dynamically you can set one of the collection to itself to cover change notification to the control.
Inside this I'd put a viewbox with a canvas in it.
Grab an outline of a hand from somewhere. You want to get a geometry out of this so look for a svg preferably.
Maybe https://www.flaticon.com/free-icon/stop-hand-silhouette_57659
Then download and install InkScape.
Use this to trace bitmap if that's all you have then save as > xaml.
Open that file in notepad and you'll see a path with a set of sort of co-ordinates. Grab those. These can be used to define a geometry you use as a resource or directly used as the Data to a path.
I use such a resource for the email "icon" in this:
https://social.technet.microsoft.com/wiki/contents/articles/32610.wpf-layout-lab.aspx
Or you could probably use one of the hand icons from syncfusion's metro studio ( free ) https://www.syncfusion.com/downloads/metrostudio
A Path can be used for your hand.
You then want 5 itemscontrols for your thumbs and fingers.
You could maybe make each of them a usercontrol as well but I'd try 5 controls for a first iteration.
They should template each item they're given into a green rectangle defined in itemtemplate.
Position 5 of them to taste on your hand's digits.
Bind their itemssources by index to your collection and use a converter to return the number of objects specified by that. So if it's 3 then you generate three objects.
That viewbox is there to scale everything. So you can size your control however you like and the rings will stay on the fingers.
In one of my previous apps I needed to add controls to a flowlayoutpanel in a winforms project dynamically, but I needed them to stop loading once there was no more room in the panel for them to fit.
To achieve this I wrote: https://github.com/LucasMoffitt/WordFiller/blob/master/WordFiller.Controls/WordLayoutPanel.cs
This basically just sets a property to false if an inbound control touches a rectangle I draw at the bottom of the panel.
While trying to replicate this behaviour in WPF I can't find any way in which I can force a WrapPanel to stop taking in controls if it's full.
I've attempted to override the Arrange and Measure methods but they only get called once all the controls have been added. I need to be able to stop the controls from being loaded at all.
Anyone have any ideas?
So I ended up taking in some suggestions and arrived at this:
https://github.com/LucasMoffitt/CustomWrapPanel
basically it's what I was doing to begin with just a little tidier, and has a demo app.
I encourage all contributions if anyone finds a nicer way of doing it!
You could check ActualHeight/AcxtualWidth against DesiredHeight/DesiredWidth. When DesiredHeight becomes larger than ActualHeight - the panel began overlapping.
I need to create a WPF application which is maximized and which rotates amongst about 10 different screens. Each screen will take the entire area and show different content.
I already know how to maximize the window with
My question is what is best to put inside that window to achieve what I want?
Ideally I'd be able to have 10 different .xaml files and I just load one after the other to take the entire screen. I'm not sure the best approach for accomplishing this in WPF.
Thank you!
One quick way to do this is to use WPF's built in page navigation. By making your root window a NavigationWindow and each view a class derived from Page (similar to work with to a UserControl or Window) you can just set the NavigationWindow.Source to a relative URI that points to the page you want to show (like a web browser) and simply switch it as needed.
This sounds like a classic MVVM application, which is simply too much to put into detail here. Google MVVM or Model-View-ViewModel, or pick up the book Advanced MVVM by Josh Smith (widely regarded as an expert in such things).
However, this is basically what you are going to have:
One class, the ViewModel, is an abstraction of the data that you need to bind to
Your data Model
A View for each thing you want to show. A View is simply something that holds your UI, be it a DataTemplate or a UserControl. Each View is bound to the ViewModel
The Views are the things that will "rotate" (although rotate in WPF implies animation and/or transformation). How you switch between them is up to you, although it sounds almost like something that would be done with a DispatcherTimer and animation (i.e. like fading between pictures in a slideshow).
This question is really too broad for this forum - you will need to do quite a bit of research on WPF fundamentals before proceeding. Again, MVVM is a good direction to start.
EDIT: Something More Lowbrow, per OP Request
This is probably as simple was you can make it (and still create separate XAML files for each piece of content):
First, create 10 UserControls (XAML files) for the stuff you want to show.
Next, add an instance of each of these user controls to your main window. Set the Visibility of each of these to Collapsed, except the first one to show.
Put a "Next" button on the main window.
In the code-behind, handle the Click event for the Next button. In there, keep track of which UserControl is visible, by name. Set the one that is currently visible to Visibility.Collapsed, and set the next one that is supposed to be visible to Visibility.Visible.
This is certainly an ugly solution, and not very WPF-ish, but it will get the job done.
Scenario: I have a (numeric) textbox, a button, and a label. When the button is clicked I'd like the label to "animate" to the numeric value in the textbox (like a spinning dial)
Given:
a) that animations in storyboards cannot have databindings (because they are not FrameworkElements)
b) the lack of triggers in Silverlight
What is the best, and with least coupling of the view model to the view's storyboard, way to update the target animation value and start the animation when the button is clicked?
Note: The scenario is conceptual, so don't concentrate on the specifics of 'animating' numbers or anything
If your goal is strictly to reduce the code-behind in the view I think that an attached behaviour on the Label would work for this. The attached behaviour on the label would expose the number to be animated to and when this number changes an animation (in code) would be run to animate from the old value to the new value.
One drawback is that your animation is now in code, unless you store a templated (just has fake values to start with) version of it in a resource file somewhere where you can load it as needed and replace the templated values.
This article from Josh Smith seems to be the authority on Attached Behaviours;
http://joshsmithonwpf.wordpress.com/2008/08/30/introduction-to-attached-behaviors/
I recently had to solve a similar problem in an MVVM application. My problem was that I needed to animate a container's height from zero to auto. Since Auto is a dynamic value I recognized that the animation (or storyboard) would need to be built (or manipulated) on demand. The solution that I put in place involved using view code-behind to update and fire the animation.
This isn't the most MVVM-friendly approach; however, animations in WPF can be tricky in XAML. Since this solution is really just a workaround for a XAML limitation it seems okay to tie the code directly to the view. Likewise, if the views were mocked then there would be no framework elements to animate, so it really wouldn't make sense to place this code on the VM side.
Does anybody have a better approach?