Windows 8 questions (Why App.Current.Resources? Why Use GridView Items?) - c#

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.

Related

Is it possible to initialize a UserControl as a StaticResource to be used inside a ContentControl

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?

How can I dynamically update bindings in MvvmCross?

I know that bindings in MvvmCross get hooked up initially when we call SetContentView. However, I am dynamically creating a new view and the bindings from it are not being hooked up. Is there a way to get the MvvmCross bindings to hook up for views created after SetContentView was initially called?
In my example specifically - I am coding for the Google Glass client and implementing multiple cards. When certain information is sent to Glass, I create a new card and inflate an xml file for the new card's view but the bindings are not getting hooked up.
Code to create the new card:
_cardScrollAdapter.AddItem(LayoutInflater.Inflate(Resource.Layout.new_panel_view, null))
Portion of XML that creates the binding:
local:MvxBind="Bitmap BitmapConverter(PanelViewModel.Image); Visibility Visibility(PanelViewModel.ShowImage)"
The issue is related to the fact that you are passing a View inflated using the Android LayoutInflater.Inflate method, instead of using the MvvmCross BindingInflate method. With a using Cirrious.MvvmCross.Binding.Droid.BindingContext; at the top of your file, the following should work:
_cardScrollAdapter.AddItem(this.BindingInflate(Resource.Layout.media_panel_view,null));

WinRT Application

I am busy developing a WinRT Application.
I want to access the value of RichEditBox defined in page BasicPage1.xaml into the code behind the page BasicPage2.xaml i.e in BasicPage2.xaml.cs?
Is there anyway to get the value of the RichEditBox(defined in BasicPage1.xaml) in BasicPage2.xaml.cs ?
Thanks in anticipation.
Are you familiar with MVVM? Basically the idea is to not rely to much on the control layer for business data, instead share these information on another layer, in this case the model or view model.
So lets say you want to want to load a project and have a dialog with a textbox containing the path to a project, which the user can modify. So you would store the path in a model called ProjectInformation, this object you can now pass to other views (to be more precise, view models and then views) and use the data there. The important part here is lifetime, your model propably lives much longer than your view, so the data is stored and reused in the places where its necessary.
A simple way to do this is to give your textbox a name in the XAML and then access that textbox via the name in the code behind.
<TextBox Name="myTextBox"/>
then in the code behind you can do this
myTextBox.Text = "blah";
A better way is to use binding so that updating the textbox automatically updates the property you are bound to. Have a look at this post textbox binding example
For a rich edit textbox you should be able to do this:
set
myTextBox.Document.SetText(Windows.UI.Text.TextSetOptions.None, "Here is text");
get
string value = string.Empty;
myTextBox.Document.GetText(Windows.UI.Text.TextGetOptions.AdjustCrlf, out value);
See this post for more information
Do you need to send it through when navigating to the other page? Then you can do it like this:
this.Frame.Navigate(typeof(BasicPage2),textbox.Text);
and at the BasicPage2.xaml.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var textbox= e.Parameter;
...
}
But i also highly recommend using MVVM in your application. With MVVMLight you can implement this quite easy and quick.

Setting text of controls on form dynamically

I have a WinForms app that I am currently implementing a translation engine in. What I have so far is a bunch of text documents that follow the syntax like:
messages.manualupdate="There is a manual update available for ProgName.\n\nDo you want to update to version {0}.{1}.{2}{3}?"
messages.errorcopy="Clicking OK will copy the error so you can paste it elsewhere!"
messages.error="Error"
messages.notsupported.title="Unsupported client"
messages.notsupported.message="This version is no long supported. Please wait for an update."
I have lots of these for different languages, for example:
messages.manualupdate="é disponibile un'aggiornamento manuale del programma ProgName.\n\nVuoi aggiornare alla versione {0}.{1}.{2}{3}?"
messages.errorcopy="Cliccando OK eseguirete una copia degli errori visualizzati"
messages.error="Error"
messages.notsupported.title="Client non supportato"
messages.notsupported.message="Questa versione non è utilizzabile al momento. attendi il prossimo aggiornamento!"
I then parse this into a DynamicObject which I can access like language.messages.notsupported.error. What I would like to know is if I can somehow link all the controls on the form to use variables from the dynamic object on creation. For instance I have a button on my form that I want to have the text "Error" in. Before the form shows, I set the language variable to the users chosen language, and then when the form shows it simply loads the text from language. Is there a way to do this in the designer rather than having to write a method that is called in the Forms constructor as it seems to me like a little bit of a waste to set all the button text to a value and then change them all when the form loads. I'm looking for a sort of binding, but to the controls Text parameter.
Anyone have any ideas?
MSDN has a walkthrough on string localization that might be of use to you link
Honestly, the approach you are trying to avoid looks best to me. I will suggest you to create a property for the control where you are trying to set the Text. In Set attribute, check for the language selected and get the appropriate text for you.
public string Error
{
set { _errorLabel.Text = value; }
}
private void SetText()
{
if(EnglishSelected)
Error = "English";
}
Regarding waste of time, well, I will just suggest not to set anything in designer and directly set the property in Load form. But I would like to add one more point here that any of the approach will not hit your application speed. First its about making your application expandable and maintainable and then about making it fast. Setting logical things in designer is always a bad practice. If your application is not tiny/small then I will suggest you to follow some design patterns like MVP and move all this logical things in Presenter. Not trying to preach but just suggesting.
And yes, in our company one of team is working in localization part of the application. Using resource may be a better way of doing this.
Hope it helps.

ASP.NET Custom Controls - Composites

Summary
Hi All,
OK, further into my adventures with custom controls...
In summary, here is that I have learned of three main "classes" of custom controls. Please feel free to correct me if any of this is wrong!
UserControls - Which inherit from UserControl and are contained within an ASCX file. These are pretty limited in what they can do, but are a quick and light way to get some UI commonality with designer support.
Custom Composite Controls - These are controls that inherit from WebControl where you add pre-existing controls to the control within the CreateChildControls method. This provides great flexibility, but lack of designer support without additional coding. They are highly portable though since they can be compiled into a DLL.
Custom Rendered Controls - Similar to Custom Composite Controls, these are added to a Web Control Library project. The rendering of the control is completely controlled by the programmer by overriding the Render method.
My Thoughts..
OK, so while playing with custom composites, I found the following:
You have little/no control over the HTML output making it difficult to "debug".
The CreateChildControls (and subsequent methods) can get real busy with Controls.Add(myControl) everywhere.
I found rendering tables (be it for layout or content) to be considerably awkward.
The Question(s)..
So, I admit, I am new to this so I could be way off-base with some of my points noted above..
Do you use Composites?
Do you have any neat tricks to control the HTML output?
Do you just say "to hell with it" and go ahead and create a custom rendered control?
Its something I am keen to get really firm in my mind since I know how much good control development can cut overall development time.
I look forward to your answers ^_^
I say go ahead with the custom rendered control. I find that in most cases the composite can be easier done and used in a UserControl, but anything beyond that and you'd need to have a finer degree of control (pun unintended) to merit your own rendering strategy.
There maybe controls that are simple enough to merit a composite (e.g., a textbox combined with a javascript/dhtml based datepicker, for example) but beyond that one example, it looks like custom rendered controls are the way to go.
Here's another extension method that I use for custom rendering:
public static void WriteControls
(this HtmlTextWriter o, string format, params object[] args)
{
const string delimiter = "<2E01A260-BD39-47d0-8C5E-0DF814FDF9DC>";
var controls = new Dictionary<string,Control>();
for(int i =0; i < args.Length; ++i)
{
var c = args[i] as Control;
if (c==null) continue;
var guid = Guid.NewGuid().ToString();
controls[guid] = c;
args[i] = delimiter+guid+delimiter;
}
var _strings = string.Format(format, args)
.Split(new string[]{delimiter},
StringSplitOptions.None);
foreach(var s in _strings)
{
if (controls.ContainsKey(s))
controls[s].RenderControl(o);
else
o.Write(s);
}
}
Then, to render a custom composite in the RenderContents() method I write this:
protected override void RenderContents(HtmlTextWriter o)
{
o.WriteControls
(#"<table>
<tr>
<td>{0}</td>
<td>{1}</td>
</tr>
</table>"
,Text
,control1);
}
Rob, you are right. The approach I mentioned is kind of a hybrid. The advantage of having ascx files around is that on every project I've seen, designers would feel most comfortable with editing actual markup and with the ascx you and a designer can work separately. If you don't plan on actual CSS/markup/design changes on the controls themselves later, you can go with a custom rendered control. As I said, my approach is only relevant for more complicated scenarios (and these are probably where you need a designer :))
I often use composite controls. Instead of overriding Render or RenderContents, just assign each Control a CssClass and use stylesheets. For multiple Controls.Add, I use an extension method:
//Controls.Add(c1, c2, c3)
static void Add(this ControlCollection coll, params Control[] controls)
{ foreach(Control control in controls) coll.Add(control);
}
For quick and dirty rendering, I use something like this:
writer.Render(#"<table>
<tr><td>{0}</td></tr>
<tr>
<td>", Text);
control1.RenderControl(writer);
writer.Render("</td></tr></table>");
For initializing control properties, I use property initializer syntax:
childControl = new Control { ID="Foo"
, CssClass="class1"
, CausesValidation=true;
};
Using custom composite controls has a point in a situation where you have a large web application and want to reuse large chunks in many places. Then you would only add child controls of the ones you are developing instead of repeating yourself.
On a large project I've worked recently what we did is the following:
Every composite control has a container. Used as a wrapped for everything inside the control.
Every composite control has a template. An ascx file (without the <%Control%> directive) which only contains the markup for the template.
The container (being a control in itself) is initialized from the template.
The container exposes properties for all other controls in the template.
You only use this.Controls.Add([the_container]) in your composite control.
In fact you need a base class that would take care of initializing a container with the specified template and also throw exceptions when a control is not found in the template. Of course this is likely to be an overkill in a small application. If you don't have reused code and markup and only want to write simple controls, you're better off using User Controls.
You might be able to make use of this technique to make design-time easier:
http://aspadvice.com/blogs/ssmith/archive/2007/10/19/Render-User-Control-as-String-Template.aspx
Basically you create an instance of a user control at runtime using the LoadControl method, then hand it a statebag of some kind, then attach it to the control tree. So your composite control would actually function like more of a controller, and the .ascx file would be like a view.
This would save you the trouble of having to instantiate the entire control tree and style the control in C#!

Categories