How to Add dynamic control instead of static control? - c#

I have a collection with fields cityname, statename and countryname and I bind that collection to my wpf form. I want to display the cityname in a Textbox, the statename in a combobox and the countryname in a combobox. All the textboxes and comboboxes should come dynamically. How can I do this job?
Any one suggest me how to design this form dynamically in wpf using MVVM I am trying to do this code but not get result properly. Either I get everything as textbox or combobox, but what i need is textbox and combobox as specified.
<Border Margin="3.5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125" />
<ColumnDefinition Width="*" MinWidth="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock x:Name="tbFieldTag" Cursor="Hand" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="Wrap" Margin="10,0,0,0" Text="{Binding Path=CardField.FieldTag}" />
<TextBox Margin="10,0,0,0" x:Name="txtFieldData" Grid.Column="1" MaxLength="{Binding Path=CardField.MaximumLength}" Text="{Binding Path=CardField.FieldData, Mode=TwoWay}" />
<!--<ComboBox Margin="10,0,0,0" x:Name="comboFieldData" Grid.Column="1" Text="{Binding Path=CardField.FieldTag}"/>-->
</Grid>
</Border>

The key to your problem are DataTemplates. These allow you to bind your view to a collection of custom objects.
You should have a ViewModel that is exposing an ObservableCollection<TLocation> where TLocation is a class that is exposing public properties Cityname, Statename and Countryname.
In your View you need to show a ContentControl, say a ListBox, having it's ItemSource property bound to the ObservableCollection.
Then you set the DataTemplate for the Listbox to something like:
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path=CityName}" />
<ComboBox Text="{Binding Path=StateName}" />
<ComboBox Text="{Binding Path=CountryName}" />
</StackPanel>
</DataTemplate>
Another approach is to use a DataGrid. See this article

Related

C# WPF Get Selected Combobox Binding Fields

I have a combo box that has a data template with 3 fields bound from a data table.
The problem I have is I want to find out which item I have selected in the combobox and get access to one of the bound fields.
The SelectedIndex gives me the position but I want the id so I can pass that directly to the Insert method.
You can see below I have 3 fields on for each combo box item.
I would like to identify the primary key for the selected item, "uid"
<ComboBox Name="cboCombo" Width="300" Height="42" TabIndex="3"
ItemTemplate="{StaticResource ComboBoxKey}"
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True"
SelectedValuePath="uid"
FontSize="12"/>
<DataTemplate x:Key="ComboBoxKey}"">
<Grid Height="35" Width="300" ShowGridLines="false">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0"></ColumnDefinition>
<ColumnDefinition Width="200"></ColumnDefinition>
<ColumnDefinition Width="75"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding uid
Style="{StaticResource txtStyle}"></TextBlock>
<TextBlock Grid.Column="1" Text="{Binding field_1}"
Style="{StaticResource txtStyle}"
TextWrapping="Wrap"></TextBlock>
<TextBlock Grid.Column="2" Text="{Binding field_2}"
Style="{StaticResource txtStyle}"></TextBlock>
</Grid>
</DataTemplate>
I think i've got it:
DataRowView dr = (DataRowView)cboComboBox.SelectedItem;

C# XAML Universal Apps - Change StackPanel's width as TextBoxes inside grow

I have a few TextBoxes inside a StackPanel like this:
...
<StackPanel Orientation="Horizontal">
<TextBox Text="1"></TextBox>
<TextBox Text="1"></TextBox>
<TextBox Text="1"></TextBox>
</StackPanel>
...
I would like the StackPanel to grow as the TextBoxes are typed into, but instead, the TextBoxes wrap as more text is added.
How can I make the StackPanel to grow as the TextBoxes are typed into?
Thanks in advance!
When I try your solution it works for me.
But you could try to add the property TextWrapping="NoWrap" to each TextBox or create a Style.
Or you could use instead of a StackPanel a Grid which does also work
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefiniton Width="Auto" />
<ColumnDefiniton Width="Auto" />
<ColumnDefiniton Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="1" />
<TextBox Grid.Column="1" Text="1" />
<TextBox Grid.Column="2" Text="1" />
</Grid>

Checkbox in ItemTemplate

I have a <Checkbox/> in my <GridView.ItemTemplate>. How do I handle the <Checkbox/> as to the element in which it is?
For example, I want to delete item when checkbox checked.
I think should write here. But what?
private void CheckBox_Checked_1(object sender, RoutedEventArgs e)
{
}
Here's My XAML:
<GridView Margin="0,10,0,0"
RelativePanel.AlignHorizontalCenterWithPanel="True"
x:Name="GridColections"
IsItemClickEnabled="True"
SelectionMode="None"
ItemsSource="{x:Bind DS.AllRem, Mode=OneWay}"
ItemClick="GridColections_ItemClick" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:GetRem" >
<Grid Margin="-2,0,-6,0" BorderBrush="LightGray" BorderThickness="1" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Stretch" TextWrapping="Wrap" Text="{x:Bind ReminderName}" Margin="5,5,0,0" FontSize="20"/>
<TextBlock TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="1" Width="600" TextWrapping="Wrap" Text="{x:Bind ReminderDescription}" Margin="5,5,0,0" FontSize="12"/>
<CheckBox Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Center" Checked="CheckBox_Checked_1"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
The problem is that you almost certainly want to be able to use the DataContext in your click handler but you won't get that easily by just having a reference to the CheckBox which will be the sender argument in your callback. Normally what you would do here is create a Command on your item's view model and bind to that and any additional information that you would want to pass in you would pass in through the CheckBox's CommandParameter.
Once you do this you are now operating in your view model with a reference to whatever piece of information that you need through the command parameter (for instance you could set CommandParameter = "{Binding}" to pick up the entire data context which would be the item's view model and that would be accessible from your Command as an argument to it). You should be able to solve your issue this way.

How to Bind all ListBox's Items to the same Property?

I have a ListBox with the following DataTemplate:
<DataTemplate x:Key="ItemTmp">
<Border Name="Border" BorderBrush="Aqua" BorderThickness="1" Padding="5" Margin="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Item1}"></TextBlock>
<TextBlock Grid.Column="1" Text="{Binding Path=Item2}"></TextBlock>
<TextBox Grid.Column="2" Text="{Binding Path=UpdatedGrade,UpdateSourceTrigger=LostFocus,Mode=TwoWay }" />
</Grid>
</Border>
</DataTemplate>
</UserControl.Resources>
Means, I want that everytime user writes something in one of the text boxes , it will update the same field in the ViewModel - UpdatedGrade , problem is that it doesn't work.
When I just bind a single TextBox to this field, it does works, for example:
TextBox Grid.Row="3" Text="{Binding Path=UpdatedGrade,UpdateSourceTrigger=LostFocus,Mode=TwoWay }"></TextBox>
Does anyone have any idea how can I do it?
The DataContext of a ListBox item is of the individual item in the collection, so it's trying to find to a Property of that item.
As long as this is not a windows store app, you can do something like this:
Text="{Binding Path=DataContext.UpdatedGrade, UpdateSourceTrigger=LostFocus, Mode=TwoWay, RelativeSource={RelativeSource AncestorType=UserControl}}"
with win8 apps you can't find ancestor as easily, so you'd have to give the name of the element that contains the context
Text="{Binding Path=DataContext.UpdatedGrade, UpdateSourceTrigger=LostFocus, Mode=TwoWay, ElementName=MyUserControl}"
I'm unsure of how this would act--binding directly to the textbox--it might update UpdatedGrade in the DataContext, but again, I'm not sure.
Text="{Binding Path=Text, UpdateSourceTrigger=LostFocus, Mode=TwoWay, ElementName=MyTextBox}"

Definine one grid to hold all the items of a ListBox in stead of a grid for each using a DataTemplate

I have a ListBox that is bound to a list of Persons. I want to show the items of the listbox in a grid. I can accomplish this with the code below, but the problem is that with this code each item has its own grid. I want one grid to contain all items so that each column in the grid is automatically scaled to the width of the longest string. I suppose I should bind data to a Grid in stead? How?
<ListBox ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=Name}" />
<TextBlock Grid.Column="1" Text="{Binding Path=Age}" />
<TextBlock Grid.Column="2" Text="{Binding Path=Gender}" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can still accomplish this using the Grid inside of your DataTemplate. You would just need to specify the IsSharedSizeScope attached property on your ListBox and SharedSizeGroup property on the ColumnDefinitions you want to synchronize.
Alternatively you can define the ListBoxes' panel as a Grid, but I don't recommend that unless your Person objects have an ordering property which can be used easily to bind to Grid.Row.

Categories