C# MVVM - how doI prevent duplicated content in a multiple combobox selection? - c#

I have five ComboBoxs which are using the same enum content.
Each ComboBox should not have the same value.
If box one has selected content "beef", box two has selected the content "beer".
And now I select "beer" in box one, and both contents should switch. I'm actually using a method with checks both with if and else (working, but really boring).
Is there a smarter solution?
For each box I have one of this trigger and Model.BoxOneValue, Model.BoxTwoValue...
private void OnBoxOneChange(PropertyChangedEventArgs e)
{
}

Can't post a full answer without that xaml but if you can pass it a ComboBox via CommandParameter
public RelayCommand<object> BoxChangeCommand { get { return new RelayCommand<object>(OnBoxChange); } }
private void OnBoxChange(Object comboBox)
{
ComboBox list = comboBox as ComboBox;
if (list != null) {
//do stuff
var items = list.Items;
var selectedItem = list.SelectedItem;
}
}
you'll need using System.Windows.Controls for the ComboBox
There is another way too, by binding your SelectedItem in the xaml to your VM and you can press a button on the frontend and the VM with figure everything out.

Related

Clear ComboBox if RadioButton is deactivated

I have five RadioButton and five ComboBox controls.
Each RadioButton is connected to a ComboBox.
When I activate one RadioButton, the corresponding ComboBox, it gets enabled.
Now when I choose another RadioButton, the information in the previously selected ComboBox should clear but does not!
I have tried with ComboBox.Clear() as well as ComboBox.Reset(), but it doesn't work.
Here is my code for one of the ComboBox and RadioButton
if (radioButtondinner.Checked == true)
{
comboBoxdinner.DataSource = DList.Dwork();
comboBoxdinner.DisplayMember = "dinner";
}
As I said in comment: you can use one Combobox and only to change data sources when you check other RadioButton that should work sure
But If you want to have more Combobox then just type in else statements
comboBox.DataSource = null;
// create a check change event and use this.
private void radioButtondinner_CheckedChanged(object sender, EventArgs e)
{
if (!radioButtondinner.Checked)
{
// if you want to clear only the text or selected item text
comboBoxdinner.Text = String.Empty;
// if you want to clear the entire data source
comboBoxdinner.DataSource = null;
}
}

How to change comboBox Item Source when this comboBoxSelectionChanged property is called WPF C#

So I am using external API which is providing class called CatInfoType which have for example int number catid and string catname.
I have a combobox with properties
< ComboBox x:Name="listOfCategories_comboBox" ... SelectionChanged="listOfCategories_comboBox_SelectionChanged" DisplayMemberPath="catname" />
Then in MainWindow cs file I have:
1) list of this class
List<CatInfoType> displayedCategories_List = new List<CatInfoType>();
2) in constructor
var comboBox = listOfCategories_comboBox as ComboBox;
comboBox.ItemsSource = displayedCategories_List;
3) after some button is clicked then I am filling values of combobox:
foreach (var item in allCategories_list)
{
if (item.catparent == 0)
{
displayedCategories_List.Add(item);
}
}
Until now everything is fine, but I would like to change combobox items after same comboBoxSelectionChanged is called:
private void listOfCategories_comboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
CatInfoType selectedCategory = listOfCategories_comboBox.SelectedItem as CatInfoType;
int selectedCategoryId = selectedCategory.catid;
int selectedCategoryParentId = selectedCategory.catparent;
displayedCategories_List.Clear();
foreach (var item in allCategories_list)
{
if (item.catparent == selectedCategoryId)
displayedCategories_List.Add(item);
}
var comboBox = listOfCategories_comboBox as ComboBox; // I think those two lines are useless
comboBox.ItemsSource = displayedCategories_List;
}
However the combobox items are not getting changed. I was trying to do it in few ways. None of them get the result.
How I may do this ? Change comboBox Items "on live". After one of those item is pressed I want to clear the list and add new items to be displayed.
I hope code above and description is showing what I would like to do. In case you have questions feel free to ask.
try use ObservableCollection<CatInfoType> instead List<CatInfoType>

How access to selected items of a ListView from another class? in WPF C#

I have two views of WPF (Vista1.xaml and Vista2.xaml), and they are part of a MainWindow.xaml.
In the Vista1.xaml i have a listview, where the user selects some items by clicking and the Vista2.xaml has a button.
I want that when the user clicks on the button of Vista2.xaml, get the items that the user previously selected in the listview of Vista1.xaml.
I have class in the Vista1.xaml.cs ListViewItem_PreviewMouseLeftButtonDown method that captures the user selects the item in the listview.
the code is as follows
private void ListViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var item = sender as ListViewItem;
if (item != null && item.IsSelected)
{
...
}
}
I appreciate your help
Add a public property to you MainPage that contains the data you want to pass between Vista1 and Vista2. Then, in your event handler of Vista1, set the property and on the button click of Vista2 read the property.

ComboBox SelectedIndex MVVM WPF

I have a ComboBox bound to an ObservableCollection of tbPublications which populates as it should. I then select a row from a DataGrid which fires another Create form in which I insert a new record into tbPublications, all good.
When I close said create form and return to my ComboBox form I am clearing and re-reading in the one new item to my ObservableCollection, returning the user to the item they've just created. The ComboBox then displays the one item from my newly populated collection, all good.
My problem is that on returning to my ComboBox form, the new publication is not set as selected item in the ComboBox display, the user has to click the ComboBox then select the item.
I can't use SelectedIndex = "0" in my view XAML as I want to show the whole ObservableCollection in my ComboBox on page load.
Is there any way to use a method in the ViewModel maybe to solve this issue, something maybe such as..
private void SetSelectedIndex()
{
if (MyObservableCollection.Count == 1)
{
//Set selected indexer to "0";
}
}
Found a solution to this, not sure if it's the cleanest 'MVVM' solution...
After reading in my ObservableCollection I invoke this method:
if (_ModelPublicationsObservableList.Count == 1)
{
SelectedPublication = _ModelPublication;
SetSelectedIndex();
}
Here's the method which gets the current main window and sets the SelectedIndex:
private void SetSelectedIndex()
{
ArticlesDataGridWindow singleOrDefault = (ComboBoxWindow)Application.Current.Windows.OfType<ComboBoxWindow>().SingleOrDefault(x => x.IsLoaded);
singleOrDefault.comboBox1.SelectedIndex = 0;
}
Did you consider using the SelectedItem property of combobox? You can bind the selected item property of combobox to get or set the selected item.
XAML
<ComboBox ItemsSource="{Binding Path=Publications}" SelectedItem="{Binding Path=SelectedPublication, Mode=TwoWay}" />
ViewModel
public class ItemListViewModel
{
public ObservableCollection<Publication> Publications {get; set;}
private Publication _selectedPublication;
public Publication SelectedPublication
{
get { return _selectedPublication; }
set
{
if (_selectedPublication== value) return;
_selectedPublication= value;
RaisePropertyChanged("SelectedPublication");
}
}
}
If you want to set the selected item from View model,You can set the SelectedPublication property as-
SelectedPublication = Publications[0];
Or you can locate the required item in the Publications collection and assign it to SelectedPublication property.
Add UpdateSourceTrigger=PropertyChanged to your binding.
SelectedItem={Binding Path=SelectedPublication, Mode=TwoWay}, UpdateSourceTrigger=PropertyChanged}

Change WPF DataTemplate for one entry change

In my wpf app, I've written Mouse double click event for ListBox entries. When I double click on single entry, it will be posted on server. My problem is, when I post any entry to server, I want to change DataTemplate of that entry only. In the below code which I've written, it posted all the entries to the server. so, please suggest the ways to change DataTemplate for single entry only. "Harvest_TimeSheetEntry" is my ListBox entry.
Also see comments in the code.
C# code:
private void listBox1_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
//Submit clicked Entry
if (sender is ListBoxItem)
{
ListBoxItem item = (ListBoxItem)sender;
Harvest_TimeSheetEntry entryToPost = (Harvest_TimeSheetEntry)item.DataContext;
if (!entryToPost.isSynced)
{
//Check if something is selected in selectedClientItem and selectedProjectItem For that items
if (entryToPost.ClientNameBinding == "Select Client" || entryToPost.ProjectNameBinding == "Select Project")
System.Windows.MessageBox.Show("Please select your Project and Client");
else
{
Globals._globalController.harvestManager.postHarvestEntry(entryToPost);
System.Windows.MessageBox.Show("Entry posted");
DataTemplate tmpl = (DataTemplate)this.FindResource("DefaultDataTemplate");
listBox1.ItemTemplate = tmpl; // **Here I want to change DataTemplate for only posted entry.**
}
}
else
{
//Already synced.. Make a noise or something
System.Windows.MessageBox.Show("Already Synced;TODO Play a Sound Instead");
}
}
}
Try using the following line in replacement of your line:
Harvest_TimeSheetEntry entryToPost = (Harvest_TimeSheetEntry)item.Content;
This will access the data item inside the ListBoxItem. Of course it depends on how you have set the DataContext of the items... I'm assuming that you have set the DataContext of the ListBox.ItemsSource and not on each ListBoxItem. Note that if you have set the DataContext of each ListBoxItem, that could be your problem.

Categories