Since I am a beginner in WPF, I have a question which might be basic in nature.
I have a datagrid which has a combobox.
The xaml which I have written is:
<DataGridComboBoxColumn Header="ControlOption" Width="100"
SelectedItemBinding="{Binding Path=DataGridComboxBox_Control}">
<DataGridComboBoxColumn.ItemsSource>
<col:ArrayList>
<sys:String>Database1</sys:String>
<sys:String>DataBase2</sys:String>
</col:ArrayList>
</DataGridComboBoxColumn.ItemsSource>
</DataGridComboBoxColumn>
I have 3 values which should be there in the drop down of the comboBox.
1. WorkStream1
2. WorkStream2
3. WorkStream3
Now how do I write the codebehind for the ComboxBox.
Please do give me pointers in this. :)
Very much appreciated.
Ashutosh
Sorry, haven't quite understood you. Do you want to replace the itemssource of combobox from code behind?
In this case you can to bind combobox's ItemsSource to property. Like that:
<Controls:DataGridComboBoxColumn Header="Gender" ItemsSource="{Binding Path=Genders}" />
and in code behind will be smth like
public ObservableCollection<string> Genders
{
get {
return _genders;
}
set { _genders = value;
PropertyChanged(this, new PropertyChangedEventArgs("Genders"));
}
}
If you meant smth else, explain please. May be I've understood you in a wrong way
use datagrid_PreviewKeyDown function to capture keypressed in grid. if the cell is focused use
datagrid.BeginEdit() to convert cell from text block to combo box.
i think this will help to solve the issue.
Related
I am having a furious struggle with the WPF Combobox in our bi-languge application.
I have the combobox binded to a collection. I have a button that replaces the values of the collection with their corresponding string values in another language.
What is the problem: I select a value from the drop down list. I change the language, by pressing a button, then the displayed value remains on the old language, but when the drop down is dropped the values in in are replaced with the right ones.
Here is my XAML:
<ComboBox x:Name="ProjectClassComboBox"
Width="150"
ItemsSource="{Binding Path=ProjectClassCollection}"
DisplayMemberPath="Name"
SelectedValuePath="Id"
SelectedValue="{Binding Path=RegionContext.CurrentItem.ClassNomenclatureId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
Update: Because it is asked in the comments I must add that
the collectionis a custom class of ours, DERIVED from ObservableCollection, that is fairly complex. The collection items must be implementing INotifyPropertyChanged, and the collection has a listener to the PropertyChanged event of each item.
It just looks like the displayed text of the combo is not updated, when the drop down list and the selected item value is updated.
Binding ObservableCollection (and derrived class too) works only in case where you add or delete items, cause that's the action that invokes change event. If you need to manipulate data inside collection I suggest using BindingList. Maybe some kind of wrapper would be solution for you.
Do one thing. In the button click,
1. get the selected index in the combo box
2. Replace all the strings in the collection
3. set the selecteditem property of the combobox using the selected index that we have stored earlier in the step 1.
So, it's a bit late but we just encountered the same problem on a project that needs to support multiple languages.
Our solution was to return a new instance of ObservableCollection on the property getter.
So, your code should look like this:
<ComboBox x:Name="ProjectClassComboBox"
ItemsSource="{Binding Path=ProjectClassCollection}"/>
And in your ViewModel:
public ObservableCollection<Project> ProjectClassCollection
{
get {return new ObservableCollection<Project>(){_projectClassCollection};}
set {...}
}
This code is a quick snippet from my memory. It will not work if you just copy-pasta, but the idea is that another collection instance worked for us.
We tried to call OnPropertyChanged(nameof(ProjectClassCollection)) but that didn't work. We tried to set UpdateSourceTrigger=PropertyChanged in XAML but that didn't work either. Having a new instance worked.
Hope this helps and saves you time, cheers!
I have a Longlistselector that is getting the text through data binding. My problem is I need it to be localized so it displays the right language, how is the right way to do it?
I tried the first way that came to my head, but I thought it doesn't work:
MainPage.cs
_UserAdBL.Add(new UserAdB("{Binding LocalizedResources.UsText01, Source={StaticResource LocalizedStrings}}"));
Any help will be appreciated, thanks!
If I understand you correctly, you want to get the value of the {Binding LocalizedResources.UsText01, Source={StaticResource LocalizedStrings}} XAML binding in C#.
So use AppResources.UsText01 like so
_UserAdBL.Add(new UserAdB(AppResources.UsText01));
In a project I have a very tricky requirement I don't know how to solve:
I have several datagrids in a single wpf window (I use MVVM) all binded to some collection in the linked ViewModel.
The customer wants to edit each of these grids, either within the grid or in a common textbox (like in excel).
I'm banging the head on how to do the latter. What I would do is bind the textbox with a property in the viewmodel, but when the value is changed there, I need to change the value in the original property binded with the datagrid cell accordingly. In other words, I need to know what collection and which property of that collection I need to change with the data in the textbox accordingly .
I tried several ways but with no luck.
Reflection? DependencyProperty? What else?
Any help?
Thank you
Assuming that you're using the built-in WPF DataGrid, you'll need to setup your grid similarly:
<DataGrid SelectionUnit="Cell" SelectionMode="Single" ItemsSource="{Binding Data}" SelectedCellsChanged="DataGrid_OnSelectedCellsChanged">
...
</DataGrid>
Also give your TextBox a name:
<TextBox x:Name="textBox" DockPanel.Dock="Top" />
In the code-behind, you'll need to manually wire up this event, since apparently the DataGrid doesn't allow you to bind to the selected item/cell/value when using SelectionUnit="Cell":
private void DataGrid_OnSelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
if (e.AddedCells.Count == 0)
this.textBox.SetBinding(TextBox.TextProperty, (string) null);
else
{
var selectedCell = e.AddedCells.First();
// Assumes your header is the same name as the field it's bound to
var binding = new Binding(selectedCell.Column.Header.ToString())
{
Mode = BindingMode.TwoWay,
Source = selectedCell.Item,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
this.textBox.SetBinding(TextBox.TextProperty, binding);
}
}
I tried getting this done without code-behind but after looking around it didn't seem like this was possible.
In addition to tencntraze answer I used this code to get te property bound to the cell
var property = (selectedCell.Column.ClipboardContentBinding as Binding).Path.Path;
I've been tying different things / reading up on this issue for awhile now and have not yet found an answer. Hopefully you guys can help.
I have an observablecollection of type string. I want to bind this collection to a datagrid and be able to edit/delete/add to the collection. Here is my xaml:
<DataGrid ItemsSource="{Binding Movies.Titles}" CanUserDeleteRows="True" CanUserAddRows="True" Height="300">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"/>
</DataGrid.Columns>
</DataGrid>
The same observablecollection is also bound to a listbox. I want to be able to edit the collection using the datagrid method (above) and see the changes/edits in the listbox. The delete/add is working correctly, but when I edit a string inside a grid cell and it loses focus, the string goes back to what it originally was and never gets updated.
Thanks a lot for any help / suggestions.
Wow, I went to do this yesterday and was stuck with a DataGrid that would add a new line for my ObservableCollection. After research, I realized why. Strings and immutable.
I found this question and unfortunately it didn't have an answer. So I can't leave this empty of an answer.
So here are the answers I found:
DataGrid cannot update a string collection by adding, editing, or removing strings.
I found a workaround to wrap the string in a StringWrapper object. Here it is.
public class StringWrapper
{
public string Text { get; set; }
}
I didn't like either answer.
The original question asker, moncadad, looks like he wants a one column DataGrid. He probably just wants to add and remove strings from an ObservableCollection without a lot of code. Edit probably isn't too important since that can be done by delete and add again.
I ended up doing this myself with a reusable usercontrol I made called StringListBox.
A ListBox for strings that supports add and delete
Basically the idea is to create the look of a DataGrid with a Label, a ListBox, a TextBox and an Add button and since this is a control, it has to work with ObservableObject or List in one control.
This give you Add and Delete. I doesn't provide edit.
Hope this helps the next guy.
Actually it works, you should just use
Mode=OneWay
in your binding.
I hope this helps!
i've been banging my head on this for the last hours...
I have a User Control called "DayItem", and i want to show it 48 times in another UserControl called "DayPanel".
Let me mention this is done in MVVM style, but i'm only experiencing, and a straight way would by fine for an answer.
I have an ObservableCollection<DayItem> in the DayPanel model, and in the Xaml there's an <ItemsPresenter />.
if i do
this.ItemsSource = DayItems;
everything show up fine.
but, i wanna be able to use those DayItems in the UI like a list... to support multi-select etc.
so i tried using a ContentControl, and set it's content to the ObservableCollection.
but it just shows the ObservableCollection object's ToString text.
so i guess i need a DataTemplete there...
but why do i need a DataTemple to show a Control?
it's already styled in it's own Xaml, i don't wanna repeat it's styling again.
or maybe i'm totally wrong, anyway i need help :x
Edit:
I got this to work, saying what DataType wasn't necessary or even possible.
and in the code behind i told the listbox, that it's ItemSource was the ObservableCollection.
now i've ran into other problems... ListBox related...
There are Gaps between each control in the ListBox, which messes up the layout
and also i need to figure out a way to select multiple items by dragging...
thanks for the help so fat
First, you need a view model for you DayItem user control. Lets call it DayItemViewModel. Also I suppose you DayPanel also has a view model called something like DayPanelViewModel. Then, you DayPanelViewModel would expose a collection of DayItemViewModel instances:
public class DayPanelViewModel
{
public ObservableCollection<DayItemViewModel> DayItems { get; set; }
}
Then, in your DayPanel.xaml:
<UserControl x:Class="DayPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<UserControl.Resources>
<DataTemplate x:Key="DayItemTemplate"
DataType="{x:Type my:DayItemViewModel}">
<my:DayItem />
</DataTemplate>
</UserControl.Resources>
<Grid>
<ListBox ItemsSource="{Binding DayItems}"
ItemTemplate="{StaticResource DayItemTemplate}" />
</Grid>
</UserControl>
Try using ListBox, since that implements multiselect...
Also it might be wise (for MVVM) if you do not contain DayItems, but DayItemModel's in your DayPanelModel, and set the ListBox's ItemTemplate to present each DayItemModel with a DayItem.