*Intro: *
I'm working with a standard MVVM framework and I have two listboxes from which I want to be able to select one item from. The listboxes are binding to different ObservableCollections of the same class.
After binding to the ViewModel, I want to be able to represent the selected Item on the same window, from either of the Listbox depending on which item I am selecting.
ViewModel -
private KisesaSearchResultViewModel _selectedPerson;
public KisesaSearchResultViewModel SelectedPerson
{
get
{
return _selectedPerson;
}
set
{
_selectedPerson = value;
OnPropertyChanged("SelectedPerson");
}
}
private KisesaSearchResultViewModel _selectedSearch;
public KisesaSearchResultViewModel SelectedSearch
{
get
{
return _selectedSearch;
}
set
{
_selectedSearch = value;
SelectedPerson = value;
OnPropertyChanged("SelectedSearch");
}
}
private KisesaSearchResultViewModel _selectedMatch;
public KisesaSearchResultViewModel SelectedMatch
{
get
{
return _selectedMatch;
}
set
{
_selectedMatch = value;
SelectedPerson = _selectedMatch;
OnPropertyChanged("SelectedMatch");
}
}
XAML -
<ListBox ItemsSource="{Binding Path=MatchedMembers, Mode=OneWay}"
ItemTemplate="{StaticResource SearchResult}"
SelectedItem="{Binding SelectedSearch}">
</ListBox>
<ListBox ItemsSource="{Binding Path=SelectedMatchList, Mode=OneWay}"
ItemTemplate="{StaticResource SearchResult}"
SelectedItem="{Binding SelectedMatch}">
</ListBox>
I want to display information as such:
<TextBlock Grid.Row="1" Text="{Binding Path= SelectedPerson.FullName}" FontSize="18" FontWeight="Bold" Style="{StaticResource PInfo}" />
<TextBlock Grid.Column="0" Grid.Row="2" Style="{StaticResource Info}" Margin="30,0,0,0" Text="{Binding Path=SelectedPerson.Age}"/>
Question:
I need to have SelectedSearch and SelectedPerson because I want to be able to change SelectedPerson independtly. At this point, the SelectedPerson is getting set by the SelectedSearch setter, but it is not binding to the Textblocks. I am using OnPropertyChanged, but do I need to do something else like use an Event Handler? Also, slightly unrelated, but can I restrict a WPF window so that only one item from two different Listboxes is selected at a time?
Related
I am currently learning the MVVM design pattern for WPF and I would like to bind my CheckBoxes based on the SelectedItem of my ComboBox which is data binded to a Dictionary where the key is my device serial number and the value is a ViewModel for that device.
Ideally, my SelectedItem should be the value which is IOBoardViewModel.
<ComboBox Name="io_boards_list"
ItemsSource="{Binding IOBoards}" DisplayMemberPath="Key" SelectedValuePath="Value"
HorizontalAlignment="Left" Margin="361,28,0,0" VerticalAlignment="Top" Width="657" Height="35"/>
This is where I am most unclear: how to bind these bool values in my IOBoard Model.
<CheckBox IsChecked="{ Binding Value.io_board.s0 }" Content="Input 0" Canvas.Left="10" Canvas.Top="10" Height="15"/>
<CheckBox IsChecked="{ Binding Value.io_board.s1 }" Content="Input 1" Canvas.Left="10" Canvas.Top="36" Height="15"/>
<CheckBox IsChecked="{ Binding Value.io_board.s2 }" Content="Input 2" Canvas.Left="10" Canvas.Top="63" Height="15"/>
In my IOBoardViewModel I refer to the actual Model which is where I hold my bool value.
public Dictionary<string, IIOBoardViewModel> IOBoards { get; private set; }
public FullIOBoard io_board
{
get { return _io_board; }
}
Here is a snippet from my IOBoard Model:
public bool s0
{
get
{
return _s0;
}
set
{
_s0 = value;
OnPropertyChanged("s0");
}
}
public bool s1
{
get
{
return _s1;
}
set
{
_s1 = value;
OnPropertyChanged("s1");
}
}
public bool s2
{
get
{
return _s2;
}
set
{
_s2 = value;
OnPropertyChanged("s2");
}
}
I would like to know if I have the right idea on how to bind the data together in the MVVM pattern, and if not, I would greatly appreciate insights or advice.
UPDATE:
I have thought of a method that I could use where I bind the SelectedItem of the ComboBox (which would be the Dictionary's identifying serial number to a variable in my ViewModel):
public string SelectedItem
{
get
{
return _SelectedItem;
}
set
{
_SelectedItem = value;
}
}
Now I believe I should bind my IsChecked for the CheckBox to
<CheckBox IsChecked="{ Binding IOBoards[SelectedItem].s0 }" Content="Input 0" Canvas.Left="10" Canvas.Top="10" Height="15"/>
However I am still unable to get the checkbox to update even though I've hardcoded one of the signals to always be true:
_io_board.s0 = true;
_io_board.s1 = (inputSignal & 0x02) == 0x02;
you can bind directly to SelectedItem of ComboBox by referring to it by name:
<CheckBox IsChecked="{ Binding SelectedItem.Value.io_board.s0, ElementName=io_boards_list }"
EDIT
Solution was actually a proper setting of SelectedItem, SelectedValue and SelectedValuePath properties.
<ComboBox
Grid.Column="1"
Padding="5"
DisplayMemberPath="PositionName"
IsSynchronizedWithCurrentItem="False"
ItemsSource="{Binding Positions, Mode=OneWay}"
SelectedItem="{Binding SelectedOperatorPosition, Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
SelectedValue="{Binding SelectedOperatorPosition.PositionName}"
SelectedValuePath="PositionName" />
QUESTION
I am trying to bind ComboBox SelectedValue with DataGrid SelectedItem using MVVM pattern.
ComboBox ItemSource is Shifts property. I want it's SelectedValue to be bound with SelectedShift property, which is updated each time user selects another OperatorModel from DataGrid.
Although SelectedOperator setter sets SelectedShift value to SelectedOperator.Shift, ComboBox doesn't get updated.
View
Debugging ViewModel Property setter
My ViewModel:
private Operator selectedOperator;
public Operator SelectedOperator
{
get
{
return selectedOperator;
}
set
{
selectedOperator = value;
if (selectedOperator != null)
{
SelectedShift = selectedOperator.Shift;
}
OnPropertyChanged(nameof(SelectedOperator));
}
}
private Shift selectedShift;
public Shift SelectedShift
{
get
{
return selectedShift;
}
set
{
selectedShift = value;
OnPropertyChanged(nameof(SelectedShift));
}
}
XAML:
<ComboBox
Grid.Column="1"
Padding="5"
DisplayMemberPath="Name"
ItemsSource="{Binding Shifts}"
SelectedValue="{Binding SelectedShift}"
SelectedValuePath="Name" />
i think you should use SelectedItem="{Binding SelectedShift}
I want to bind a ComboBox item to a string, but it does not work. My code is below.
Code in view:
<ComboBox
SelectedValuePath="content"
SelectedItem="{Binding ProductName}"
......
<ComboBoxItem>1111111111</ComboBoxItem>
<ComboBoxItem>2222222222222</ComboBoxItem>
<ComboBoxItem>333333333333</ComboBoxItem>
</ComboBox>
Code in view model:
private string _productName;
public string ProductName
{
get { return _productName; }
set
{
if (_productName != value)
{
_productName = value;
RaisePropertyChangedEvent("ProductName");
}
}
}
I assume you want to get the text from the ComboboxItem and not the ComboBoxItem iteself.
So you are binding the wrong information. This should work.
<ComboBox
SelectedValuePath="content"
Text="{Binding ProductName}"
......
<ComboBoxItem>1111111111</ComboBoxItem>
<ComboBoxItem>2222222222222</ComboBoxItem>
<ComboBoxItem>333333333333</ComboBoxItem>
</ComboBox>
Selected Item is of type ComboBoxItem, it will not accept String.
If you want to display product name in some other place try maybe something like this:
<TextBox Text="{Binding ElementName=my_ComboBox, Path=SelectedItem}"/>
Just a suggestion.
You already use a binding for the SelectedItem, why don't you set up another binding for the Items using the ItemsSource? So you would not need to add them statically in your view.
In addition you would not have the trouble to wonder whether you deal with instances of ComboxItem or String with your SelectedItem binding.
In case of the binding via ItemsSource you can be sure that the SelectedItem is a string.
Here is the code:
<ComboBox
SelectedValuePath="content"
SelectedItem="{Binding ProductName}"
ItemsSource="{Binding ProductNames}"
</ComboBox>
In your view model (or code behind) you define the ProductNames:
public String[] ProductNames
{
get
{
return _productNames;
}
set
{
if (_productNames!= value)
{
_productNames = value;
RaisePropertyChangedEvent("ProductNames");
}
}
}
String[] _productNames;
public NameOfConstructor()
{
List<String> productNames = new List<String>();
productNames.Add("A");
productNames.Add("B");
productNames.Add("C");
ProductNames = productNames.ToArray();
}
If it was possible that the list of names changes during execution, I would use a ObservableCollection<string> instead String[].
It should be like this
Create an observable collection of Product in View Model. Lets Say ProductCollection
Bind to the ComboBox ItemSource as given below
<ComboBox Name="productComboBox" Width="200" Height="30" ItemsSource="{Binding ProductCollection}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ProductName}"></TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
if you want to show in textbox somewhere
use this
<TextBox Text="{Binding ElementName=productComboBox, Path=SelectedItem}"/>
I am trying to populate an Observable Collection Based on What items are selected from the AutoCompleteBox. May I get some guidance towards where I am going wrong. It's not Binding the way I would like it to.
xaml:
<telerik:RadAutoCompleteBox x:Name="RadAmortAutoBox" HorizontalAlignment="Left" Grid.Column="1" Grid.Row="6" VerticalAlignment="Top" SelectedItems="{Binding AmortDates, Mode=OneWay}"
ItemsSource="{Binding Payments}" DisplayMemberPath="PaymentNo" TextSearchPath="PaymentNo" Width="708" />
ViewModel:
public ObservableCollection<int> amortDates;
public ObservableCollection<int> AmortDates
{
get { return amortDates; }
set
{
amortDates = value;
RaisePropertyChanged("AmortDates");
}
}
I'm completely new to WPF.
I'm making a simple application in the MVVM pattern.
I have a viewmodel with a model referenced in it. The model contains some netelements I want to put in a combobox.
Here is the relevant part of the viewmodel:
public class MainWindowVM : ViewModelBase
{
private Model _model = null;
public Model Model
{
get
{
return _model;
}
}
#region ActiveElement
private NetElement _activeElement = null;
public NetElement ActiveElement
{
get
{
return _activeElement;
}
set
{
if (_activeElement != value)
{
_activeElement = value;
RaisePropertyChanged("ActiveElement");
if (ActiveElementChanged != null)
ActiveElementChanged(this, EventArgs.Empty);
}
}
}
}
I would like to be able to select a NetElement in a combobox and set the ActiveElement to it.
here is the relevant part of my current XAML:
<ItemsControl Background="White" IsTabStop="True" ItemsSource="{Binding Path=Model.RootNet.Elements}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Margin="2,6">
<Hyperlink Command="{Binding Path=I'm not able to figure out what to write here}">
<TextBlock Text="{Binding Path=Name}" />
</Hyperlink>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
This is not a combobox but a list of TextBlocks, but you can see where it is going.
How can I set the ActiveElement from the view?
Create a binding for the SelectedItem property of the ComboBox to your ActiveElement property:
<ComboBox SelectedItem="{Binding Path=ActiveElement}" ... />
then set the DataContext property of the view to your view model.