I have my userControl element on a window and now I must connect comboboxes inside these userControls to ObcervableCollections on the ViewModel. But I can't. I linked the collections to the items, but get the following error - when I change the selection in one combo box, I automatically get the changes for the others. How to unbind the SelectedItem of a combo box to use 1 collection for multiple items with an independent selection. My control has this interface (for example).
<uielements:DeviceParametersControl Grid.Column="1"
Margin="2,2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
EndColor="#3B191919"
NumberOfSystem="2"
MaxFaultPressureValue="{Binding DataContext.SelectedParameter[1].MaxFaultPressureValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
MaxWorkPressureValue="{Binding DataContext.SelectedParameter[1].MaxWorkPressureValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
MinWorkPressureValue="{Binding DataContext.SelectedParameter[1].MinWorkPressureValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
TestTimeValue="{Binding DataContext.SelectedParameter[1].TestTimeValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
PulseTimeValue="{Binding DataContext.SelectedParameter[1].PulseTimeValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
PauseTimeValue="{Binding DataContext.SelectedParameter[1].PauseTimeValue, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
PulsesCount="{Binding DataContext.SelectedParameter[1].PulsesCount, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
PulsesAcceleration="{Binding DataContext.SelectedParameter[1].PulsesAcceleration, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
Mode="{Binding DataContext.SelectedParameter[1].Mode,UpdateSourceTrigger=PropertyChanged, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
StartColor="#3BFFFFFF"
TestName="{Binding DataContext.SelectedParameter[1].Name, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
UpdateDataToDbCommand="{Binding DataContext.UpdateDataToDbCommand,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
UpdateDataToPlcCommand="{Binding DataContext.UpdateDataToPlcCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Control}}}"
ItemsSource="{Binding DataContext.Parameters, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
DisplayMemberPath="Value"
SelectedValuePath="Id"
SelectedValue="{Binding DataContext.SelectedItem4Two, Mode=OneWayToSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
</uielements:DeviceParametersControl>
CodePudding user response:
Use a different Object to each Components and selection like this :
XAML Code :
<Window x:Class="TestMVVMLight.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestMVVMLight"
mc:Ignorable="d"
DataContext="{Binding Main, Source={StaticResource Locator}}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<ComboBox HorizontalAlignment="Left" Margin="27,113,0,0" SelectedValue="{Binding SelectedParameter1}" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Parameters}" DisplayMemberPath="Value"/>
<ComboBox HorizontalAlignment="Left" Margin="171,113,0,0" SelectedValue="{Binding SelectedParameter2}" VerticalAlignment="Top" Width="120" ItemsSource="{Binding Parameters}" DisplayMemberPath="Value"/>
</Grid>
</Window>
ViewModel Code :
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
ObservableCollection<Parameter> parameters = new ObservableCollection<Parameter>();
for (int i = 0; i < 6; i )
{
parameters.Add(new Parameter { Value = "Value " i });
}
Parameters = parameters;
}
public ObservableCollection<Parameter> Parameters { get; set; }
public Parameter SelectedParameter1 { get; set; }
public Parameter SelectedParameter2 { get; set; }
}
CodePudding user response:
// XAML
// first control
ItemsSource="{Binding DataContext.Parameters, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
SelectedValue="{Binding DataContext.SelectedItem4One, Mode=OneWayToSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
// second control
ItemsSource="{Binding DataContext.Parameters, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}"
SelectedValue="{Binding DataContext.SelectedItem4Two, Mode=OneWayToSource, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
// ViewModel
// all strings from database
public ICollectionView Parameters => this._model.Parameters.View;
// array for selected elements - it has 5 elements for each control
public ObservableCollection<Parameters> SelectedParameter => this._model.SelectedParameter;
public object SelectedItem4One
{
set
{
if (value == null || value == _selectedItem4One) return;
_selectedItem4One = value;
this._model.GetParametersById(0, (int)_selectedItem4One);
}
}
// - function from Model
public async Task GetParametersById(int index, int id)
{
try
{
var response = await _dataAccessService.DatabaseInterface
.GetByIdAsync(id)
.WithTimeout(TimeSpan.FromSeconds(TimeOutConnection));
this.SelectedParameter[index] = response.FirstOrDefault() ?? new Parameters();
OnPropertyChanged(new PropertyChangedEventArgs(nameof(SelectedParameter)));
}
catch (Exception e)
{
Message =
"Ошибка получения набора параметров для выбранного рецепта из базы данных по Id.\n" e.Message
e.InnerException;
OnMessageChanged(new PropertyChangedEventArgs(nameof(Message)));
}
}