How to get Control from DataTemplate and ControlTemplate ? thinks so much - xaml

When i define a control in DataTemplate, how to get reference of this control ?
If the control in ControlTemplate of Style , how to get ?

You should instead tell us why you would need to reference a control inside a template.
Consider that the control will be rendered multiple times, so getting a single reference does simply not make any sense.

The most common approach to this is to 'name' the element that you wish to locate via x:Name="MyElementName", you can then use the FindName method to locate the names element. If your DataTemplate is being used in an ItemsControl to render multiple copies of yoru XAML markup, then clearly there will be a number of elements that share this same name. For this reason, there is a concept known as XAML namescope, you should read up on this to understand the scope of the name you provide.
If you require a more generic method for searching for elements in the visual tree, try Linq-to-VisualTree, you can use it to query you UI, for example:
var itemsFluent = this.Descendants<TextBox>()
.Where(i => i.Ancestors().FirstOrDefault() is Grid);
The above query will find all TextBoxs that have a Grid as a direct parent.
Finally, if you can avoid doing any of this, by using databinding, or event bubbling then do so! it is much easier.

Related

Access UserControl child controls?

I have a custom UserControl. That control has a Grid which I can access by name. But I can't seem to access the subcontrols from UserControl's constructor.
I can do:
this.LayoutRoot
but not
this.LayoutRoot.MyChildControl
how can I access this control programmatically?
If you used the x:Name attribute: x:Name="MyChildControl", you cen refference it in code behind regardless of nesting.
x:Name sets the FrameworkElement.Name property (but can be also used on objects other then FrameworkElement) and results in creating a field with this name which is assigned to in InitializeComponent().
So you can call simply:
this.LayoutRoot...
this.MyChildControl...
Note that FrameworkElement has a FindName method, which will work similarly to what you expected:
this.LoayoutRoot.FindName("MyChildControl")
By code you can create new object of your UserControl and then you can easily access user control elements by it's name.
MyUserControl ctrl=new MyUserControl();
ctrl.LayoutGrid.Background=new SolidColorBrush(Colors.Blue);
or generally
ctrl.ChildrenName
UserControl's child control can access by UserControl.Content. If you want to access your Grid's children, please use this.LayoutRoot.Children. You can enumerate this collection.

Force reapply of ItemTemplateSelector in WinRT

I have a GridView as my zoomed out view in a SemanticZoom control. This GridView uses a custom DataTemplateSelector as the ItemTemplateSelector. It shows an item for each content group that my app shows.
The template is different depending on whether the group is empty or not. This works fine on load, but it doesn't update when a group becomes empty or stops being empty.
I've found that the ItemTemplateSelector is only run when the page is first shown. How can I force the DataTemplateSelector get run again.
The WPF questions on this topic all suggest triggers, but these aren't available in WinRT XAML.
I've found an answer to a similar WPF question that answers this in a way that works in WinRT:
https://stackoverflow.com/a/11327087/31569
Basically you set the ItemTemplateSelector to null and then set it again. Like this:
var templateSelector = MyGroupView.ItemTemplateSelector;
MyGroupView.ItemTemplateSelector = null;
MyGroupView.ItemTemplateSelector = templateSelector;
This works, but happy to be told if there is a better way to do this.
I find it easier to just just remove the item in need updating from the collection and adding it back. This forces the GridView or ListView to apply the template. This is easy to do in MVVM world.
var itemToReload; //The object who's template needs updating
var reloadIndex = this.SomeCollection.IndexOf(itemToReload);
this.SomeCollection.Remove(itemToReload);
this.SomeCollection.Insert(reloadIndex, itemToReload);
One thing to note, is that if the item is a "Selected" item, you'll need to reapply that selection.

Can I apply "StaticResource" to element in run-time?

Can I apply "StaticResource" to element in run-time?
I know I can use "StaticResource" to element in xaml files. But, I want to know how to use it from C# (code-behind).
A StaticResource is a static defined resource, usually defined in the <X.Resources> element, for any element or page.
In C# you simply access it with X.Resources["MyResource"] like you should do {StaticResource MyResource}.
Not really with the same meaning. StaticResources are "static" in the sense that their value is resolved during Xaml parsing. The XamlParser will resolve the resource by examining the resource dictionary the ancestor FrameworkElement Resource properties that are also in the same xaml and then the Application.Resources if necessary.
If you happen to know where to find the resource you want to assign using C# code then it is as simple as in Claus' answer. However if you only know the name of the resource but not which dictionary its found in then its much tricker.
It is possible to write a routine (you can probably find one in SO or elsewhere on the web) that you can use to hunt up the Visual tree using the VisualTreeHelper looking at all the Resource properties along way. You could probably get away with this but be aware that this may search more dictionaries than the original Xaml version would and its possible for you to get some unexpected value.

Coldfusion object inheritance sanity check needed

I need to know if I am going about something the right way.
For a given page, I am instantiating an object for the page itself. Let's call that object myPage. Within the page I have containers (usually div tags). When I go to an admin component to work with a specific div, I instantiate an object for that as well. Let's call that myDiv.
Now, one of the things I want to work with for a given div is the styling of that div. So normally I would think that I'd just put in some style-related methods, such as myDiv.getPadding() or myDiv.getBackgroundColor(), etc.
But it occurs to me that I may eventually have other objects for which I may also need to do style-related stuff.
Given this, should I then create a separate style.cfc? Would that then be extended by the div object? Or would the style object extend the div object? My understanding is that the more specific object extends the less specific one, but I am not sure which is more specific in this case: is it the div object, which references a specific div, or the style object, which provides a specific set of data?
Thanks in advance!
First, unless you need to write styles on-the-fly, I would create one or more stylesheets and link them dynamically, instead of creating them dynamically.
Assuming, however, that you do need to create them on-the-fly...
I would not have either the control (div) extend the style or vice-versa. A style is not a more specific definition of a div, nor is the reverse true. What I would do is create a style object that only contains the display meta-data for a given element or element set. This can be contained within your control/div object (not an extension), or can be part of the page object. The style is definitely related to the control, but I would not combine them, as that makes it harder to separate content and presentation.
By no means am I saying this is the best approach, but if you really wanted to use CFCs to style your pages, you could have a DivTag.cfc extend an HtmlTag.cfc, which would act as your base class for all HTML tags. You could then compose a StyleAttribute.cfc into your HtmlTag.cfc to work with any style properties, such as background colors and padding. So then you would end up calling functions like myDiv.getStyle().getPadding().
In general, you should really try to favor composition ("has a") over inheritance ("is a") and not get too crazy with your component hierarchies. In this case, I'd recommend using CSS files to style your pages.

How to correctly inherit from a usercontrol defined in XAML in Silverlight

If I have a usercontrol (in Silverlight) that I've written, that uses XAML to define it's appearance, how can I make a customised version of it?
i.e. I have MyControl.xaml & MyControl.xaml.cs
What do I need to do if I want a "SpecialisedControl" child class? I assume I just make a new code file, then inherit from MyControl. But what if I want to change the appearance of the base class - then what do I do?
I wrote this thinking you were talking about WPF, rather than Silverlight, but there may be enough overlap for this to be helpful, so I'm posting it, anyway.
If by "change the appearance of the base class" you mean "provide a new template", then what you need is probably a CustomControl, not a UserControl.
The best way to accomplish this is to follow the example set by other Microsoft controls, such as Button or ListBox:
Create a class that derives directly from Control (or whatever is closest to your control).
If any properties will need to be exposed to the control (such as text on a button, for example), make sure that you properly define them as DependencyProperties.
As described here, create a ResourceDictionary called Themes/generic.xaml and add a style for your class that includes a template (don't give the style a key).
Use TemplateBindings for any properties of elements on your control that need to get values from your control.
If you'll need to attach any event handlers to elements in your template, give them a unique name. Microsoft uses the convention of prefixing these names with "PART_", and I think it's a good thing to do for the sake of consistency, but it's not strictly required.
Again, if you need to attach event handlers, overload OnApplyTemplate(). In this method, you should detach any old event handlers (we certainly don't want any memory leaks!), and look for elements that have the names your provided in your template--when you find them, attach event handlers, as necessary.
This is certainly much more work than simply deriving from UserControl, but if you want to be able to totally re-template controls, like you can with the built-in controls, this is the way to do it.
On the other hand, if all you want to do is to provide a certain amount of limited customization, such as changing the background, or associating a Command with some user action, then the best thing to do is to expose DependencyProperties, which can then be set in styles for your control, or on instances of your control, itself.
In the case you mentioned of wanting to customize the look in an inherited control, the process is pretty similar: just add a default style for the new control with a new template; if you need to add more event handlers, just be absolutely certain that you call base.OnApplyTemplate().
I dunno, I like doing things with just plain objects. Here's an article that describes an easy way to slip a XAML-designed control outside your inheritance hierarchy so that you can customize appearance and behavior using SimpleThingsLikeInheritance rather than MicrosoftStuffThatAlmostWorks
http://gen5.info/q/2009/02/10/subverting-xaml-how-to-inherit-from-silverlight-user-controls/
As Mihnea's link describes, the easiest solution is to simply add a namespace in your XAML:
C#
public class MyBase : UserControl
{
}
public class FirstUserControl : MyBase
{
...
}
XAML
<local:MyBase
x:Class="FirstUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="YourAssembly" ...>
<!-- Sticking with UserControl instead of local:MyBase makes this clearer -->
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
..
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
..Your XAML
</local:MyBase>
You can solve this by using a wrapper as described in the link above.
But you can also use the strategy pattern to solve this problem.
In this post I explain how you implement these two methods.
http://www.lab101.be/2008/07/silverlight-usercontrol-inheritance/