In my application, I want to allow the user to load several arbitrary XAML files. Internally, I use XamlReader.Load() to load the XAML.
Now, it may happen that some of the XAMLs have named controls, such as
<Button Name="button" ... />
If the user accidentally loads 2 XAMLs that define the same name, an exception occurs, saying
Could not register named object. Cannot register duplicate name "button" in this scope.
So my next step was to unregister all names before loading the XAML:
foreach (FrameworkElement child in ((Grid) Content).Children)
{
if (!string.IsNullOrEmpty(child.Name))
{
UnregisterName(child.Name);
}
}
However, that's not sufficient, I still can't load the XAML for the same reason.
How do I get rid of the name of a control?
Note: while doing research on this, I found many answers for the question "How do I remove a control by its name?". That's not what I want. I want to keep the control, but un-name it.
Note: I'm not looking for workarounds. I know that I could e.g. process the XAML as plain XML, remove the names and then load it. I'd really like to know whether and how it's possible to do that in a WPF way.
I have also tried:
change the name with child.Name = null;
changing the scope with NameScope.SetNameScope(this, new NameScope());
combinations of the above
Related
I'm currently dipping my toes into writing Universal Apps for the windows platform, for one of my attempts I'd like to try and make a one of these snazzy new single page apps.
However, I'd like to re-use my code where possible so that I follow DRY principles and don't repeat any code that I don't need to.
As such, I've made a number of User controls (which all work fine on their own) and I'm attempting to embed them inside an Xaml ContentControl ultimately allowing me to swap different ContentControl objects in and out of view at run time.
So far, in my experiments, I have the following code:
XAML:
<ContentControl x:Name="CentralContextHost" Style="{StaticResource ContentControlStyle}">
<!-- The following tag is which ever user control I wish to host -->
<Universal:CentralHubControl/>
</ContentControl>
And the code behind I use to manipulate the above XAML:
public object CurrentControl; // field
if (CurrentControl == null)
CurrentControl = new Profile(); // another usercontrol
var tempswap = CentralContextHost.Content;
CentralContextHost.Content = CurrentControl;
CurrentControl = tempswap;
I would however like to try and make my code much cleaner by using something similar to the binding syntax I've seen used elsewhere by possibly creating my controls as static resources in a dictionary of some kind xaml object, then just dropping a similar deceleration to a bind in the correct position in my xaml to have them display as needed.
The problem I have is that I'm not really sure how to approach solving this problem, or if there is even a way that it can be solved. My idea is to be able to do something similar to the following fictitious bit of code.
<Universal:CentralHubControl x:Key="CentralHub" />
<Universal:Profile x:Key="PersonProfile" />
<ContentControl
x:Name="CentralContextHost"
Grid.RowSpan="2"
Content="{StaticResource CentralHub}"
Style="{StaticResource ContentControlStyle}">
This seems to work in blend but crashes badly when used at run time.
can anyone here see why that might be or what I might be doing wrong?
If you need any more info please ask in the comments and let me know, I'd love to find an answer to both questions here.
I've not played with an app that has everything in one page myself yet. If I did, perhaps I might suggest using a panel as your content host instead of a contentcontrol.
For example, if you were to have a Grid as the root of your layout, which by default it usually is. You can then add your user controls directly to the panel in the code behind by using the following line of code:
rootLayout.Children.Add(AnyUIElement).
Doing things this way may make it possible to create a new instance of the wanted user control and potentially maintain state for it.
For an MVVM style solution, I'll have to play around with the concept.
Is there a specific reason you need to use a contentcontrol that I may not have considered?
I have 2 questions regarding a tutorial that I am going through.
Q1.
Through the tutorial they use a datasource
Using the data in the app
To use the data in the app, you create an instance of the data source
as a resource in App.xaml. You name the instance feedDataSource.
BR211380.wedge(en-us,WIN.10).gifTo add a resource to an app
Double-click App.xaml in Solution Explorer. The file opens in the XAML editor.
Add the resource declaration, <local:FeedDataSource x:Key="feedDataSource"/>, to the root ResourceDictionary, after the
MergedDictionaries collection.
and then they use it in the OnLaunch method.
var connectionProfile = Windows.Networking.Connectivity.NetworkInformation.GetInternetConnectionProfile();
if (connectionProfile != null)
{
FeedDataSource feedDataSource = (FeedDataSource)App.Current.Resources["feedDataSource"];
if (feedDataSource != null)
{
if (feedDataSource.Feeds.Count == 0)
{
await feedDataSource.GetFeedsAsync();
}
}
}
I am wondering why do they store it in resource? Wy not just create an instance of the class and get the results from it?
Q2.
Later down the article they use this datasource items with "grid view items". I seen this done in their other template projects. I am wondering is there the standard way of making your interface?
At first I thought maybe just drop some image buttons on the screen and hook up their click events but now I am not sure.
The XAML Resource essentially does create an instance for you and makes it available in the Resources collection, so you could instantiate the class yourself. Having it as a resource keeps this object around and makes it accessible across the various pages in your application. You could certainly create the class explicitly, and if you enforce the singleton pattern on it, it would be semantically equivalent.
I'm not sure I see the context of your second question in the tutorial, but in general the pattern you are seeing is Model-View-ViewModel (MVVM), which is the de facto standard pattern for Windows Store apps. feedDataSource is providing the model and portions of that are assigned to DefaultViewModel, which is the DataContext for all of the binding markup in the XAML pages, which are the views. The idea behind this to separate your data from your model, so that when you do things like load a new data feed, etc., all you need to do is change the data source, and all of the data binding markup will automatically reflect the new data in your user interface.
If you find yourself writing code that looks like TextBox.Text = "My text", then you're deviating from the pattern.
I have this piece of code:-
What I want is that in button click i want put some value in user control.
I get Object reference error.
if (Page.FindControl("pr1") is Control)
{
Control previewControl = Page.FindControl("pr1");
Label titleLabelPreview = (Label)previewControl.FindControl("titleLabel");
titleLabelPreview.Text = emptxt.Text;
However, if i used it through master page it can not intialized
but if i use parent page it work properly.
But here, one more problem persisted, suppose the scenario
use a tab container
where is 3 tab panel
in first panel i used a button
when i click that button i want to change the tab panel view
means 2nd panel
but without refresh the page. and one important thing i don't want to use update panel on tab container. I do not wish to use ajax or javascript. any insight on this.
Also, would be really great if someone gives me a deep idea how to resolve object reference errors.
I read a few blogs like:_
http://www.mikesdotnetting.com/Article/62/Object-reference-not-set-to-an-instance-of-an-object-and-INamingContainer
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.passwordrecovery.usernametemplate.aspx
however, was not fully satisfied.
Another total newb question, I'm afraid: I have a LoginView with some HyperLinks inside it, but when I try to reference the HyperLink in the code behind it tells me that it doesn't exist in the "current context".
eg. hypLink1.NavigateUrl = "some/link/on/my/site.aspx"
I've figured out that it's only because it's in the LoginView that it can't find it... so what can I do to tell it to look inside the LoginView?
I thought it might be something intuitive like:
LoginView1.hypLink1.NavigateUrl = "some/link/on/my/site.aspx"
But to no avail.
Thanks for any help with this (most likely) really obvious problem!
I'm guessing that you're trying to reference the hyperlink from outside the loginview control?
At that point, you could try a FindControls operation on the LoginView:
HyperLink hypLink1 = (HyperLink)LoginView1.FindControls("hypLink1");
UPDATE
Ok, so I was confused as to what you were asking. The LoginView control only allows FindControls, and so you have to use the code snippet up above in order to reference controls internal to it.
Since the LoginView control uses templates, different controls will exist under different circumstances. As such, the code cannot ensure any given control inside the template will be alive at compile time.
So you'll have to FindControls every time you want to get a child control :'(
I have a WPF page used as an input form which contains a number of controls on one side, and a flow document reader on the other.
I want to set the content of this document reader to a specific part of a flow document which is loaded when the form is loaded, (via a loaded event).
I have found an article explaining how to do this, using fragments, but the examples shown are only expressed in XAML.
In my case I need to update the document property of the flow document reader when the user gives focus to one the controls (I have wired up the events already) therefore I need to do this in the code behind rather than XAML.
I have tried setting the document property to:
Document#Control_Sport
where Document is the name of XAML flow document and Control_Sport is the name of the fragment I need to navigate to.
However this gives an error, it doesn't like the hash sign being there.
I tried looking on MSDN but its XAML only. Is there a way I can do this through code?
Any help would be appreciated.
Felix,
Link to MSDN article: http://msdn.microsoft.com/en-us/library/ms750478.aspx#FragmentNavigation
You can navigate to any Block within a FlowDocument by calling Block.BringIntoView.
First, create a Frame object inside your Page or Window object. Setting the JournalOwnership property to "OwnsJournal" will give the document its own navigation bar (forward and back arrows plus a history). You will probably need to add additional parameters to size and locate the frame within your document as well, but I didn't include them in my example since I don't know what your app requires:
<Frame Name="MyFrame" JournalOwnership="OwnsJournal" />
Then, create a pack URI for your document fragment. This document is assumed to be in the same directory as the application's executable; you will need to add more to the path to navigate to the directory where the document resides in your project:
Uri MyUri = new Uri("pack://application:,,,/MyXamlDocument.xaml#MyFragment");
Then, navigate to it from inside your button's Click handler or whatever other means you like to initiate the navigation:
MyFrame.Navigate(MyUri);