Adding object on toolbox - c#

How can I add an object (in shape of rectangle for instance) to an embedded in a stack panel tag.
I was able to show the objects (as rectangle) on it using and and then using the style in an xaml file using something like:
<stackpanel ...>
<Expander Header="Controls" Content="{StaticResource FC}" IsExpanded="True"/>
</StackPanel>
but need to insert object onto toolbox dynamically. any idea how this could be done through code?
Your help will be appreciated.
Amit

Expander is a type of control which is considered to be a content type control. As such it only has one child ( the child I believe you are calling a 'toolbox') which according to your Xaml is the FC item. Do these steps to add your item to the FC item:
In Xaml give a name to the Expander so it can be accessed in code behind.
In codebehind get the expander via its name.
Access the property Content on the expander and cast it to the FC class.
Add the item you want into the FC's children or content (whatever it is you know and we don't so its my best guess).

Related

How can I instantiate complex group of controls and acces to their values? (wpf with visual studio)

I am trying to implement a list of programmatically instanced group of controls such as this one:
Example of my group
.
<Grid>
<TextBlock x:Name="TextBox_Data"/>
<TextBlock x:Name="TextBox_Time"/>
<TextBox x:Name="TextBlock_ID"/>
<ComboBox x:Name="ComboBox_Type"/>
<Button x:Name="Button_Data"/>
<Grid/>
It contains 2 TextBox, 1 TextBlock and 1 ComboBox and 1 button ( detail is pretty irrelevant tough) inside a Grid.
I would like to duplicate the Grid Parent to fill a list, and access to every values of the duplicated controls but I can not figure out how to do this.
I had in mind something equivalent to Android Studio java/xml combo but I couldn't find anything on this topic around here.
Any lead is more than welcome.
Thank you in advance for your time :)
Create a separate UserControl that contains your group of controls.
Do something similar to this:
WPF creating grid from XAML in code-behind
But, instead of code-behind, you can reference your new UserControl in a XAML.

Create an element from template programmatically

I'd like to move an element from one grid into another and have a problem to assign programmatically a template to the new instance. Further, details of my attempt.
For this purpose, I create an instance of the class together with its visual appearance from the template.
Inside the Window tag I declare the namespace:
xlmns:my="clr-namespace:myNameSpace"
I have a template in resources:
<ControlTemplate x:Key="templateX">
<StackPanel>
<Image Source="pic.png" Width="50" Height="50"/>
</StackPanel>
</ControlTemplate>
and place the element into the grid.
<Grid Grid.Row="2">
<StackPanel>
<my:someClass Template="{StaticResource templateX}" MouseMove="_event">
</StackPanel>
</Grid>
Now, I drag the element, the event "_event" fires. If I push a standard element (e.g. Rectangle) through this, I do the following at the end of the drag-n-drop chain of events:
Rectangle new_instance = new Rectangle();
// place for rectangle's form and color
NewPlace.Children.Add(new_instance);
// place for positioning the rectangle in NewPlace canvas
How, can I do the last part with the element of someClass? If I do
someClass new_instance = new someClass();
NewPlace.Children.Add(new_instance);
the template "templateX" isn't assigned to it.
The issue in this case seems to be that you want to combine two things:
an instance of your custom class (new_instance)
a control template available as a XAML resource
You already know how to create the instance of your class and how to add it to the Children list.
How to retrieve the control template (or for that matter, any other object) from a XAML resource has been discussed in other SO questions, e.g.:
How can I access ResourceDictionary in wpf from C# code?
Accessing a resource via codebehind in WPF
This leads to:
ControlTemplate template = (ControlTemplate)this.FindResource("templateX");
Now, the crucial point is that you do not want to add the control template itself to the Children list. The control template is just a set of instructions how to create a UI tree for your control and bind its properties to those of your control, where appropriate.
Instead, you want to configure new_instance to use the control template you retrieved from the resource. You can do that by assigning the control template to the Template property of new_instance:
new_instance.Template = template;
Once new_instance is added to Children, it will be displayed and it will use your custom control template.

In a ControlTemplate, I want to apply the same style to all TextBlocks

I have a class library, in which I've created default styles for TextBlock, which is applied to every TextBlock in any application that uses this class library.
The problem is that I sometimes need to exclude TextBlocks inside some other controls (say, ribbon, or my own Custom Control). The textblocks are not accessible, for instance the ones inside a tab item heade.
Is there any ways to force wpf to use another style for all TextBlocks inside one control?
Thanks
Simply add an empty (or any other) style to the resource dictionary of any ancestor of the TextBlock nested inside the control referencing the resource dictionary, in which the global style is defined. For instance, the global style defined for TextBlock won't be applied in this case (if the resource dictionary is referenced by an ancestor of the Button control):
<Button>
<Button.Resources>
<Style TargetType="TextBlock"/>
</Button.Resources>
<TextBlock Text="FooBar"/>
<Button>
Ok. As it turns out, this is not possible, see Mike Strobel's answer for an explanation of the reason and the rational behind it.
The workaround is to not create an implicit style for TextBlock, because it will affect TextBlocks inside other ControlTemplates.
What works for me is to derive a class from TextBlock, say Label and apply my style to it, and then use it wherever I want a TextBlock with that specific style.
A more "Wpf Natural" way to deal with that is to create a style with a key.

why content template of button does not have object?

i am just exploring windows phone runtime apps template. But i am seeing a weird thing.
I have Button defined in Xaml with ContentTemplate set in it. I wanted extract the Image control defined in the ContentTemplate of this button. But it is coming null.
Xaml code :-
<Button x:Name="PlayButton" Click="PlayButton_OnClick">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Name="Panel">
<Image x:Name="ControlImg"
Width="100"
/>
<TextBlock Text="text block" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
Here is button Click event :-
private async void PlayButton_OnClick(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var ct = btn.ContentTemplate; // this part is also not showing controls in it when expending ct at runtime.
var img = btn.FindName("ControlImg") as Image; // coming null
var stckpnl = btn.FindName("Panel") as StackPanel;// coming null
}
Can anybody check this out why is this happening ?
Edit :- I have broken my problem and reach this very bottom simple level and after seeing this i am just not getting why is this happening ?
That is strange behavior. It should have stack Panel and image in control template. As a work around you can use ContentTemplateRoot to get the image and stackpanel. I have test this, it is working.
((StackPanel)btn.ContentTemplateRoot).Children[0] // image
Hope this helps
Edit:
For Details about why FindName is not working see the the Remarks section on on MSDN
. Here is some relevant quotes
Important In order to use the FindName method effectively, you should understand the concept of a XAML namescope, and how a XAML namescope is created at XAML load time and then referenced and possibly modified at run time. For more info see XAML namescopes.
The most common usage of FindName in your Windows Runtime code will be from within the generated InitializeComponent call for a XAML page. In this situation, FindName is invoked only after the XAML page is loaded. InitializeComponent provides the infrastructure such that any object that was instantiated by XAML loading can conveniently be accessed by your code-behind code. You can then reference the objects as a variable that shares the same name as the markup-declared x:Name.
A run-time API such as FindName is working against a run-time object tree of the app as it exists in memory. When part of this object tree is created from templates or run-time loaded XAML, a XAML namescope is typically not contiguous within that object tree. The result is that there might be a named object in the object tree that a given FindName scope cannot find. The discontinuities between XAML namescopes that you might encounter in typical application scenarios are when objects are created by applying a template, or when objects are created by a call to XamlReader.Load and subsequently added to the object tree.
As you are using DataTemplate so the xaml object tree is not contiguous so that is why FindName is failed to find the control from the xaml tree.
hope this explains...

Creating a Scrollable StackPanel Control

How would I create a control like the example at this site as a User Control?
So, instead of doing this:
<ScrollViewer>
<StackPanel>
<!– Content –>
</StackPanel>
</ScrollViewer>
I could do this:
<ScrollableStackPanel>
<!– Content –>
</ScrollableStackPanel>
Unfortunately, there is no way to do that as a UserControl in WPF. You would need to make a custom control (instead of a user control) based on ItemsControl. It could handle this correctly.
That being said, I don't see much point in this. It's very easy to just put your StackPanel within a ScrollViewer - why reinvent the wheel?
It looks like you just need to use a ListBox. You can override the ItemContainterStyle and ListBox.Style to get rid of all the Selected behaviours and backgrounds if you want. Because a ListBox has StackPanel and ScrollViewer in it by default.

Categories