【问题标题】:Binding some combobox to one collection将一些组合框绑定到一个集合
【发布时间】:2022-01-11 11:07:56
【问题描述】:

我在一个窗口上有我的 userControl 元素,现在我必须将这些 userControls 内的组合框连接到 ViewModel 上的 ObcervableCollections。但我不能。我将集合链接到项目,但出现以下错误 - 当我在一个组合框中更改选择时,我会自动获取其他组合框中的更改。如何取消绑定组合框的 SelectedItem 以将 1 个集合用于具有独立选择的多个项目。我的控件有这个接口(例如)。

<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>

【问题讨论】:

  • “我将集合链接到项目,但出现以下错误” - 您提到您收到“以下错误”,但实际上并未将错误粘贴到您的问题中。请更新一下好吗?

标签: c# wpf


【解决方案1】:

对每个组件和选择使用不同的对象,如下所示:

XAML 代码:

<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 代码:

  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; }
  }

【讨论】:

  • 对不起。在我的例子中,SelectedParameters 是一个数组,其中包含一些用于不同控件的元素。例如,第一个 userControl 的索引为 1 并绑定到 SelectedParameters[index-1]。当组合框更改 SelectedItem 时,我从数据库收到 SelectedParameters[index-1](在此示例中)。每个控件的 SelectedValue 都不同。但这是一个问题,因为控件只有一个 ItemSource。通过在一个领域中做出选择,我在其余元素中得到了这个选择。
  • 能多放些代码看清楚吗?
  • 是的。我在上面插入了代码。
【解决方案2】:
    // 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)));
        }
    }

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
  • 这是问题所在,你在 SelectedValue 中为每个不同的控件使用相同的对象,尝试使用不同的属性
  • 抱歉,您在哪里看到相同的对象。对于第一个对象,我使用 SelectedValue="{Binding DataContext.SelectedItem4One ....,对于第二个控件 -> SelectedValue="{Binding DataContext.SelectedItem4Two .... 抱歉/但我有点不明白。
猜你喜欢
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
  • 2019-08-15
相关资源
最近更新 更多