I have defined a UserControl for DateTime picking in Windows 8 store apps. The control consists of 3 checkboxes and hast a property to channel out the selected date time.
When I include this control into another UserControl and name it, I am not able to access it from C# code.
//...Page content....
<TextBlock Text="Erledigen bis:" FontSize="16"/>
<local:DateTimePicker Name="dtp_dueUntil" />
<TextBlock Text="Wichtigkeit" FontSize="16"/>
//...Page content....
*dtp_dueUntil* is not known in my code behind file.
Am I doing something awefull wrong, or just missing a point here?
You should not access controls like that, unless you have no other choice. In your case, iF you what to expose selected DateTime in your first user control, then simply declare a Dependency Property which will hold and update this value (via DataBinding or event).
Related
I want to create a template (resource dictionary) for my app. where my type inherits the button type and I then can call it through:
<my-custom-type inherit from button>
</my-custom-type inherit from button>
And of course in WPF.
More specifically, I would like to create copies of the control in the image below with simple XAML syntax as above.
There are two approaches to this, each with their own pros and cons:
Templates allow you to reuse a section of XAML. There is (almost always) no code-behind, and you certainly won't be deriving from Button. For example, if you wanted to have a bordered text box repeated in an ItemsControl:
<DataTemplate x:Key="MyDataTemplate">
<Border>
<TextBox/>
</Border>
</DataTemplate>
Or in a button class you use ContentTemplate:
<Button ContentTemplate={StaticResource MyTemplate}>
</Button>
And you would use it as XTemplate="{StaticResource MyDataTemplate}" in an existing control that used templates. This is usually the way to go. Note that the name of the property won't be Template, but ItemTemplate, or ContentTemplate or something similar.
The exception is if you want custom behavior, in which case you use a UserControl. This technically could inherit from Button though you usually wouldn't. Subclassing a basic control should only be done if you are sure you actually want to do that. Once your user control is created, the syntax would look similar to what you have in your question:
<local:MyButton>
</local:MyButton>
Note that "local" is a made-up xmlns. Your user control would consist of whatever controls you wanted, and you can expose "attributes" to the using code via dependency properties.
I am new to WPF and C#. I need to create a Label and a Button which is in a Template.xaml. But the number of Label and Button creation is user specific which is another design.xaml. i.e if the user gives value 5, then five Label and Button needs to be created using the Template.xaml file.
I tried with something like below in design.xaml,
xmlns:local="clr-namespace:UserDesign"
<local:Template HorizontalAlignment="Left" VerticalAlignment="Top" />
<local:Template HorizontalAlignment="Left" VerticalAlignment="Top" />
<local:Template HorizontalAlignment="Left" VerticalAlignment="Top" />
But this seems to be a fixed one. I need to do this dynamically based on user input.
Without a more complete code example, it's hard to know exactly what your scenario is. But if what you're dealing with is a collection of objects, where each object corresponds to a single instance of some Template object (which presumably contains your Label and Button object), then you probably want to use WPF's data-templating features.
There is a reasonably good tutorial here: Data Templating Overview
The basic idea is to declare a DataTemplate object which is used for the ItemTemplate property of ItemsControl or a sub-class (e.g. ListBox). The DataTemplate will be declared to apply to a specific data type (e.g. the object type in your collection), and you will use bindings between the UI elements in the template and the data type to customize those elements for each data object.
Depending on what your Template itself is declared as, that might wind up being appropriate for use in a DataTemplate declaration. Or it might not…it's impossible to say without seeing an actual good, minimal, complete code example.
I have a basic project in WPF.
All it does it retrieve / update products.
As shown in the image below, the user enters an ID, the data is then displayed according to it, and the user is able to change the data and click 'Save Product' to save it to the database.
The GetProduct(int id) function retrieves a product by the ID provided.
The SaveProduct() function saves the changed fields.
Also, there are two DataTemplates:
1) For the ProductModel - includes 3 textboxes: ProductId, ProductName, UnitPrice.
2) For the ProductViewModel - includes the save/get buttons + a textbox for the user to enter the id of the desired product.
What I'm trying to do is get the changed data when a user clicks the 'Save Product' button.
The most ideal way in my opinion, is to use Binding.
Each textbox is already binded, but I have no idea how to get the binded data.
Here is an example of a binded textbox in the FIRST DataType (ProductModel):
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding ProductId}" Margin="5" Width="150" />
There is one for each of the following properties: ProductId, ProductName and UnitPrice.
IMPORTANT!: The Get/SaveProduct() functions are in the ProductViewModel class, while the actual product class is - you guessed it - ProductModel. The ProductViewModel class holds a variable that contains the current product displayed.
This is the button that's used to save the info - it is written in the SECOND DataType (ProductViewModel):
<Button Content="Save Product" DockPanel.Dock="Right" Margin="10,2" VerticalAlignment="Center" Command="{Binding Path=SaveProductCommand}" Width="100" />
The SaveProductCommand command simply fires the SaveProduct() function.
I have a few questions regarding this whole subject:
What does it mean when a binding is used like this : {Binding ProductId} ?
The default binding mode for textboxes is TwoWay as far as I remember. But in this case, ProductId/Name + UnitPrice are not dependency properties, therefore is it right that the binded values do not update/sent back when the text in the textboxes is changed? (Since there isn't an event attached to it...)
A data context was never configured in my project, but all of the "binding tags" in my XAML pages don't seem to have a defined source. Could it be that the source is actually the DataType in the DataTemplate that includes the binded objects?
The SECOND DataTemplate (the ProductViewModel one) has this ContentControl tag: <ContentControl Margin="10" Content="{Binding Path=CurrentProduct}" />.
What is it's purpose?
If a TwoWay binding were/does occur, how do I get the values from within the SaveProduct() function? Do I just refer to, say CurrentProduct.ProductName to get the changed name?
Much thanks to everyone who takes their time to answer - I appreciate it so much!
What does it mean when a binding is used like this : {Binding
ProductId} ?
The specific control property you have this binding set on is going to look for the ProductId property on the object set as the DataContext and set the propertys value in the control accordingly.
The default binding mode for textboxes is TwoWay as far as I remember.
But in this case, ProductId/Name + UnitPrice are not dependency
properties, therefore is it right that the binded values do not
update/sent back when the text in the textboxes is changed? (Since
there isn't an event attached to it...)
You do not need to make the properties within your object a DependencyProperty for TwoWay binding to occur.
A data context was never configured in my project, but all of the
"binding tags" in my XAML pages don't seem to have a defined source.
Could it be that the source is actually the DataType in the
DataTemplate that includes the binded objects?
The bindings being set within your XAML will use the object stored within the DataContext, thus if you do not explicitly set the DataContext of the view, it will be null. You should note however that the DataContext is inherited from its parent. If you are in fact setting the content by using say, CurrentProduct, then all the properties will be available to bind to per your Product type.
The SECOND DataTemplate (the ProductViewModel one) has this
ContentControl tag:
<ContentControl Margin="10" Content="{Binding Path=CurrentProduct}" />
What is it's purpose?
It is acting as the container of your CurrentProduct, which can contain one and only one item.
If a TwoWay binding were/does occur, how do I get the values from
within the SaveProduct() function? Do I just refer to, say
CurrentProduct.ProductName to get the changed name?
Without seeing the entire application, my guess is that the ContentControl is being set to the CurrentProduct and your TextBox, etc.. are all bound to the respective properties, such as CurrentProduct.ProductId, etc... The product which you want to save is in fact the CurrentProduct. When you call save within your ViewModel, you simply access the CurrentProduct and persist it as needed, where CurrentProduct.PropertyName will contain the changes which were propagated from the UI.
I am still new to silverlight and would like to ask few questions that relate to performing common tasks in silverlight that you used to do in asp.net programming (btw, I am using silverlight 4):
In silverlight, how do you access a public property on a user control in a databinding expression (without setting datacontext on the control itself)? For example, let us use a datagrid with ItemSource bound to some collection but you want to also databind to a value defined by a property your user control using the databinding expression, perhaps using 'Source' property. In asp.net you could access any public property/method using <%# expr #>.
In asp.net when a postback control was clicked and raised an event you were able to access the row in the event handler via event args and use FindControl() to find any control in the row. What's the equivalent process in silverlight?
I know how to do get the row using DataGridRow.GetRowContainingElement() but then when I use row.FindName() I can't find another control in the same row by its name, I get null back. I found postings to do something like: grid.columns[colIndex] but that's error prone since you are using index to reference the column and then you have to get the cell content to access the control you after (cell.GetCellContent(row)). It is also not universal, the above illustrated how to do it in a datagrid.
In asp.net there's OnDataBind event you can handle on majority controls, is there something equivalent in silverlight?
to create another property like the datacontext for your user control, you can create your own custom dependency property.
I would use the SelectionChanged event instead of the mouse click. it will easily tell you what row was "Added" when the user clicked the row.
At this time, no, you do not have a DataContext_Changed event in silverlight. BUT you can create your own by creating a custom dependency property, which will set the data context, and raise your own custom events. (not really sure why they didn't implement that originally, its in the WPF world).
edit to bind a property to the current control, use the following format:
Property="{Binding RelativeSource={RelativeSource Self}, Path=YourCustomProperty}"
for example, here is a textbox, where its text property is bound to its ID property:
<TextBox Height="16" HorizontalAlignment="Left" Margin="97,105,0,0" Name="txtName"
VerticalAlignment="Top" Width="120"
Text="{Binding RelativeSource={RelativeSource Self}, Path=Name}"/>
Given:
<StackPanel>
<View:ArcController x:Name="control1" Visibility="{Binding Path=CanShowDateControl, Converter={StaticResource bool2VisibilityConverter}}" />
<my1:DateLabelView x:Name="control2" DataContext="{Binding Path=DateLabelViewModel}" Visibility="{Binding ElementName=ctrlTableToolbar, Path=DataContext.IsDateReadOnly, Converter={StaticResource bool2VisibilityConverter}}" />
</StackPanel>
I have two controls (control1, and control2) inside a stackpanel, and at one time i want to show only one of the controls.
As shown in the code, the visibility of the controls is driven by "IsDateReadOnly" and "CanShowDateControl".
And, as per my viewmodel logic... CanShowDateControl = !IsReadOnly.
So, at one time I will ONLY show one of the two controls.
Question: My problem is, though i am showing only one control at a time, my xaml is creating instance of both the controls. Is it possible to create instance of only the control that i am showing?
Give that:
1) I want to show/hide using binding, so that logic lies in my viewmodel.
2) I can keep these two controls inside one wrapper control. Since i am using it at different places.
Thanks for your interest.
Use a ContentControl and ContentTemplateSelector with two DataTemplates. One for ReadOnly and other for Not ReadOnly.
In the selector, based on the property, return appropriate DataTemplate.
Other way you could go is create a Custom Control which has two (or more if more than two) properties to store two controls. Based on a condition, it should add one of them to the Visual Tree which will prevent the other one from being loaded.