We have a legacy application that utilizes VB6, the Flash ActiveX control, and Flash content to display animated movies to users. For plenty of reasons we're looking to migrate away from this. I'm hoping someone out there can answer a few questions about WPF so that we can make a determination about how best to move forward.
First, a little about our current architecture and needs. The Flash content is set up as separate SWF files, where each individual SWF represents a training module with animated content. We have hundreds of these modules. Users run this software in a disconnected fashion where their local machine may or may not have ALL of these SWF files. The current application gives the user the option of downloading the SWF modules as they're needed.
Here's how we're thinking about setting up a new solution using WPF and Blend. We've written a WPF host application that can dynamically show Blend content based on button presses or whatever. And we've created a few test modules in Blend as WPF custom controls. But there are three nagging questions:
Right now we have the custom controls within the main WPF solution, but we need to make these disconnected. I've read several things about using Application.LoadComponent but I don't know if that will work for our solution.
Each of the Blend custom controls contains one or more storyboards that control the animation. As soon as I add one of the custom controls to a container in the WPF app, ALL of the storyboards automatically start "playing". How can I programatically make it so that I start/stop certain storyboards as needed?
Let's say I want to change a text label in one of the custom controls. If we're dynamically loading the custom control, how would I access one of the text labels to make such a change?
Any tips would be greatly appreciated. Loving WPF so far and hoping we can make this work and say goodbye to Flash forever!!!
There is Manage Extensibility Framework, that is a standard approach for dynamic modules.
Anyway, I haven't used it, so I would answer the questions in other way:
1) No, LoadComponent is ised for xaml files, whereas custom control consist of code and xaml. I mean, the custom control that you can add using Add->New Item->Custom Control(WPF). So you should do something like this, with reflection and ContentControl:
Assembly asm = Assembly.LoadFile(#"C:\SomeLibrary.dll");
Type type = asm.GetType("SomeNamespace.SomeControl");
var control = Activator.CreateInstance(type) as Control;
this.myContentControl.Content = control;
2) It isn't fact. You can put the storyboards into Control.Resources and launch them manually.
((Storyboard)control.Resources["myStoryboard"]).Begin(control);
3)
control.FindName("anyname") as TextBlock;
Related
If I have an existing WPF application, and I want to assign automationIDs to the entire application where they aren't set, what's a good way to do that (for controls that aren't dynamically added)? Some sort of script that goes through all the xaml files and adds automationIDs?
My goal is to write ui tests using winappdriver.
I've googled this, but haven't found anything that seems to do what I want. Perhaps I'm misunderstanding the results. This post seems to ask the same question, but I fail to see how the answer provided is an appropriate solution.
In WPF, when a control name property has a value, this corresponds with the AutomationID you will find with a UI inspector tool like Inspect.exe. Take a look at the remarks section about automationID here. So the application should already have most of its automationIDs.
The only time I did not have a automationID for a control was when the control was created in code. A script to adjust XAML won't help you here, because there won't be XAML for those controls. Even if you used a script, you won't be sure all automationIDs will be available.
When using 3rd party controls, the availability of a AutomationId depend on the 3rd party supporting it or not. If they do not support AutomationId, you could wrap that control in a custom control and expose a AutomationID that way.
Here are some resources that might be useful:
wrapped control
UI automation of a WPF Custom Control
When working with a existing application, I usually just fill in the name property for a control as I go, so the amount of change to the application stays at a minimum.
I am building a rather large WP7 application and having a lot of fun with it. It is Pivot based and has quite a lot of pivot pages. I dynamically add and remove pivot pages based on what "mode" of the application the user has selected to keep the application look and feel as simple as possible. All is going quite well so far my app is fast responsive, not a memory or resource hog and performs background loading on demand when needed.
The Model layer contains all my business logic that represents what the application is all about. It is clean and separate from the the view-model and view layers.
The View-Model layer is an abstraction of the model to the extent that it needs to interact with the view and also contains the session-ness and workflow aspects of the application in general. It contains objects which represent the Model in a way the View needs to interact with. The view model persists the state of the application in isolated storage and supports tomb-stoning.
The View layer contains a lot of elements pivots, user controls, styles, resources etc in both xaml and the corresponding code behind. I do like Blend and the Xaml designer within visual studio 2010 however I find myself still coding/configuring the view objects within the code behind due to the nature in which they interact with each other. The code behind of the view objects is becoming quite large but still only reflects the state of the view and not the state of the application. I have made use of user controls quite a lot as this lets me build reusable components across many pivot pages however the user controls are not Blend friendly. What I am worried about is that my view might becoming more complex than it needs to be and losing the ability to coordinate the user interface design with tools like expression blend.
By customising the view this way and making use of reusable controls I have reduced my Xaml considerably and don't suffer from bloated Xaml files that other developers have mentioned but lost ability to co-ordinate with Blend. Is there are happy medium to be found? Should I be looking at designing custom controls?
[Edit]
Thanks for your reply. I think it boils down to either a lot of Xaml with a designer or break it down into user controls with more code behind. Since I moved into user controls my mindset has moved back to doing things by hand rather than with a designer (better the devil you know right!). My thoughts are should I make my user controls into skin-able custom controls or just keep going how I am and avoid using the designer. Its a bit of potato-potardo but I don't want to get into bad habits.
Custom Controls (or Templated Controls) are not directly related to your question as far as I can see. Custom controls are just controls that add new properties, events and methods to an existing control and are still capable of being 'templated' by a designer.
Creating UI in code does make it harder to design the application using Blend (and even the VS designer) because the only way to see the interface is by running the application.
A lot of the logic that creates the UI could possibly be replaced by using the Visual State Manager. Use states of the controls to design them for specific modes of the view. Only when you need extra/new states you will have to create a Custom Control.
As your question is a bit wide, feel free to add comments or extend your question so I can add more details or remove this answer when it is utter nonsense :)
I'm creating an experimental game (which would eventually become a map editor for a game) and I'd like to include a WPF window in the same project which would communicate with the game logic. This is not another render-xna-game-in-wpf-window question, I've read tons of those, I want to spawn a seperate WPF window independent from the XNA game window, but in the same program, in the same project. When I click Add Item and select WPF, all it gives me as an option is a User Control, no window or any other options etc. I've tried referencing PresentationCore but no lock either, am I missing something? I am not super with interoperability, so forgive me if what I tried is stupid. I also don't want "hacky" solutions (like creating a window and a borderless control and setting their location same etc) if it can't be done just tell it so, but I'm sure there is a relatively "clean" way of doing it since they'll be completely seperate, think of it like a very simple MVC: M Game Logic, V XNA Window, C WPF Window. And don't offer me Forms, I know how to go with forms, but I want WPF, I just work with WPF/XAML and WPF style controls more easily.
Being able to add a Window from the Add Item menu is controlled by a Visual Studio project type GUID. Have you tried to create the window xaml and cs files manually (or create it in another, test solution and Add Existing file)? Or just create a Window instance in code and show that? Also, Window is in PresentationFramework, not PresentationCore.
I'm attempting to host an ActiveX control in a WPF app. After attempting to use existing info on the web and here, I've hit a dead-end.
I need to use an ActiveX control provided to communicate with a UV power meter. They provide an application that registers and uses the control and even includes some useful demo apps. I stripped out the OCX file and put it here if needed. You won't have the power meter to talk to, but the app and demos will still load the ActiveX control successfully.
I created a simple Windows Forms application. I was able to bring the ActiveX control into the toolbar, drop it into my form, and everything is fine. The demo apps they provide do this as well.
However, getting this to work in a WPF environment is another story. The control can't be added to the toolbox and "dragged" into the app.
So far I've tried two techniques:
Technique found here. I am able to add a reference to the control, but then I enter namespace hell. The xmlns:ax namespace it suggests making cannot find the information. Here's my attempt based on what the object viewer tells me: xmlns:ax="clr-namespace:OphirUsbXLib;assembly=Interop.OphirUsbXLib"
Technique found here. This is essentially to create a new project that creates a library based on Windows Forms, which contains the ActiveX control (yikes). I am able to add the Windows Forms Host, but I cannot get access to the ActiveX control within. I can make the control public, but I still cannot call methods etc. This doesn't look like the right solution.
In short, I have an ActiveX control that works beautifully in Forms, but is a real bitch to get working in WPF.
Any insight is appreciated!
In this situation I would consider making a WinForms usercontrol which wraps the ActiveX control you are trying to use.
You could make public properties and methods which expose each of the required properties and methods on the ActiveX control, and then host this WinForms UC on the in a WPF WinFormsHost control.
I have already done something similar to this, in reverse, hosting a WPF UserControl in a WinForms UserControl, then hosting that on a VB6 Form in a legacy application.
I am very new to WPF, about 4 hours new. I am coming from ASP.net and Masterpages.
I was looking at examples of Control Template that can used to template a window so all windows look the same.
Other post
Can some direct me to an example of how it is accomplished or sample code from start to finish?
Second part:
Is the ControlTemplate the best way to go about building WPF windows client applications? What is best practices in architecting WPF windows applications.
Thanks
There really isn't a "best" way to architect WPF UIs. It all depends on the user experience your application will have.
If you want a very web-like experience you are probably better of using the pages constructs. Otherwise if you have windows, but want a common header, you may just want to make a control template for that. Maybe you need separate windows or maybe you just need to have a sub part of a grid panel change content depending on state... There are different ways to do things that are more or less suited to the type of client experience you want.
Although there are some best practices in relation to using MVC/MVVM design patterns, there isn't a "best" way to style and theme your controls. I don't consider WPF as friendly to newcomers as WinForms were, but at the same time it seems a lot more powerful in the long run. What might help you out are some basic levels of theming:
Styles: these are mainly aesthetic changes to the look and feel of basic controls and elements with some very basic support for triggering things like mouse cursor roll over. They are similar to CSS on webpages.
Control Templates: these are the more heavyweight versions of styles where you actually reconstitute a control so that, say a button can have a textbox inside of it. Where styles work on a logical level where something like a button is the most atomic element, control templates can drill down further into controls so that the border, background, text, etc of a button are seen as separate elements instead of one atomic part.
Data Templates: A more focused version of control templates meant to customize how data items in lists are drawn. If you have a bunch of pictures you don't want the file name to show up in the listbox, you'd rather have the image itself. A data template lets you accomplish this kind of thing.
So you have to ask yourself when you say, "Make all windows look the same," do you mean changes are merely aesthetic/looks (styles), customizing how a collection of items are displayed (data/item templates) or altogether changing how a standard control looks and behaves or making sure the layout of controls on a page are the same across multiple windows/pages (control templates)?
Finally, the "end to end" of the other post you linked to is pretty simple. You take the control template there, and under your tag you simply add Template={StaticResource MyTemplateName} and the template is applied. This article on MSDN is a decent intro to control templating.