Show Treeview only on item select from combobox - wpf

I have a WPF application/MVVM Pattern and it has a combobox and a treeview control.
What I wanted to do is to show the treeview control only when i select an item from the combobox.
For example : I have a Property called SelectedTransactionName
private string _selectedTransactionWsName;
public string SelectedTransactionName
{
set
{
if (_selectedTransactionWsName == value) return;
this._selectedTransactionWsName = value;
InitializaMessageElement();
}
get
{
return this._selectedTransactionWsName;
}
}
my InitializaMessageElement method will show matching transaction name to the selected item. But now I don't want to show the treeview on page load only when i do a select on the combobox.
On page load I want my window to show only the combobox.
Thanks

Your view model can contain a calculated boolean property to which your TreeView binds its Visibility property, e.g:
public bool IsTransactionNameSelected
{
get
{
return !string.IsNullOrEmpty(_selectedTransactionWsName);
}
}
You could then notify property change in the setter of the SelectedTransactionName:
set
{
if (_selectedTransactionWsName == value) return;
this._selectedTransactionWsName = value;
InitializaMessageElement();
this.NotifyOfPropertyChanged(() => this.IsTransactionNameSelected);
}
Then you can bind your TreeView Visibility property using the supplied BooleanToVisibilityConverter:
<TreeView
Visibility="{Binding IsTransactionNameSelected,
Converter={StaticResource BooleanToVisibilityConverter}" ...

Related

Change value of TextBox when SelectedIndex of a ComboBox is changed via ViewModel properties only

I have a ComboBox and a TextBox. Both of them receive values (ie SelectedValue and Text) via DataBinding to corresponding properties in ViewModel.
Upon changing the SelectedValue in this ComboBox, I want to populate a new value in this TextBox from a List<string>(which is part of the ViewModel).
I don't want to use SelectedIndexChanged event of ComboBox here to select the new TextBox. Text from List<string> of ViewModel. How can I do this?
In the setter of SelectedValue you should modify the value of the Text property and in setter of Text the PropertyChanged event shoud be fired.
public string SelectedValue
{
get { return _selectedValue; }
set
{
_selectedValue = value;
//here write your code to modify the Text property
}
}
public string Text
{
get { return _text; }
set
{
_text = value;
RaisePropertyChanged(() => Text);
}
}

Selection changed event of combobox in wpf mvvm

I am new to wpf and MVVM, and I've spent all day trying to get the value of a ComboBox to my ViewModel on SelectionChanged. I want to call a function in the selection changed process. In mvvm, what is the solution for it?
In MVVM, we generally don't handle events, as it is not so good using UI code in view models. Instead of using events such as SelectionChanged, we often use a property to bind to the ComboBox.SelectedItem:
View model:
public ObservableCollection<SomeType> Items { get; set; } // Implement
public SomeType Item { get; set; } // INotifyPropertyChanged here
View:
<ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding Item}" />
Now whenever the selected item in the ComboBox is changed, so is the Item property. Of course, you have to ensure that you have set the DataContext of the view to an instance of the view model to make this work. If you want to do something when the selected item is changed, you can do that in the property setter:
public SomeType Item
{
get { return item; }
set
{
if (item != value)
{
item = value;
NotifyPropertyChanged("Item");
// New item has been selected. Do something here
}
}
}

Multiple Binding

In my WPF Caliburn.Micro application, I have a datagrid and a checkbox with a corresponding ModelView bool property. I need to bind the checkbox to one of the datagrid's fields OneWay (which is easy). But also I want to bind the same checkbox to the property OneWayToSource. Could you please tell me how I can do that? I don't see how Multibinding can help here.
Thanks.
I don't know if this is a checkbox per row of the DataGrid, or a checkbox for a row with a particular id or index. Either way, you can use TwoWay binding, which will be the default anyway if your view model property has a getter and setter.
Your view model property should point to the instance of the record that the DataGrid is binding to.
E.g.
View Model
public ObservableCollection<Item> MyGridItems { get; set; }
public MyViewModel()
{
this.MyGridItems = ...
this.MySpecialItem = this.MyGridItems[0];
}
public Item MySpecialItem
{
get { return this.mySpecialItem; }
set { this.mySpecialItem = value; // notify of property change here }
}
View
<CheckBox IsChecked="{Binding MySpecialItem.MyBooleanProperty}" />

how to populate a datagrid after selecting an item from combobox?

i have an combobox and datagrid when user select a data from combobox the grid will be populated according to that using MVVM and entity framework
Advance thanks
In your ViewModel, create a SelectedItem property which notifies on change as so:
private object _selectedItem
public object SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnPropertyChanged("SelectedItem")
}
}
Bind your SelectedItem property of your combo box to this property.
Then watch for a change on SelectedItem and change your datagrid's source property accordingly.

WPF ComboBox SelectedItem binding

I have a WPF ComboBox and am using MVVM to bind the ItemsSource and SelectedItem properties. Basically what I want to do is when a user selects a specific item in the combobox, the combobox instead selects a different item.
<ComboBox ItemsSource="{Binding TestComboItemsSource}" SelectedItem="{Binding TestComboItemsSourceSelected}"></ComboBox>
For demo purposes, I also have a button to update the SelectedItem.
<Button Command="{Binding DoStuffCommand}">Do stuff</Button>
I have this in my viewModel:
public ObservableCollection<string> TestComboItemsSource { get; private set; }
public MyConstructor()
{
TestComboItemsSource = new ObservableCollection<string>(new []{ "items", "all", "umbrella", "watch", "coat" });
}
private string _testComboItemsSourceSelected;
public string TestComboItemsSourceSelected
{
get { return _testComboItemsSourceSelected; }
set
{
if (value == "all")
{
TestComboItemsSourceSelected = "items";
return;
}
_testComboItemsSourceSelected = value;
PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
}
}
private ICommand _doStuffCommand;
public ICommand DoStuffCommand
{
get
{
return _doStuffCommand ?? (_doStuffCommand = new RelayCommand(p =>
{
TestComboItemsSourceSelected = "items";
})); }
}
OK, so I want to have the ComboBox select the item "items" whenever the user selects the item "all".
Using the button, I am able to update the combobox's SelectedItem, and I can see this reflected in the UI
I have similar logic to update the viewModel in my setter of the TestComboItemsSourceSelected property. If the user selects "all", instead set the SelectedItem to "items" So code-wise, the viewmodel property gets changed, but this is not reflected in the UI for some reason. Am I missing something? Is there some sort of side-effect of the way I've implemented this?
Well, this is because you change the property while another change is in progress. WPF will not listen to the PropertyChanged event for this property while setting it.
To workaround this, you can "schedule" the new change with the dispatcher, so it will be executed after it is done with the current change:
public string TestComboItemsSourceSelected
{
get { return _testComboItemsSourceSelected; }
set
{
if (value == "all")
{
Application.Current.Dispatcher.BeginInvoke(new Action(() => {
TestComboItemsSourceSelected = "items";
}));
return;
}
_testComboItemsSourceSelected = value;
PropertyChanged(this, new PropertyChangedEventArgs(TestComboItemsSourceSelected))
}
}
The behaviour you are describing seems very weird for me, but if you want a "Select All" feature, the standar way is to create a combobox where items has a CheckBox.
Each item is represented by a small ViewModel (tipically with Id, Name and IsChecked properties), and you manually create a "select all item" that is added first in the ObservableCollection and subscribe to its PropertyChanged in order to set the rest o the items IsChecked property to true.

Resources