从ItemsControl中获取项目(了解DataContext)

时间:2015-04-12 03:36:13

标签: c# wpf mvvm data-binding datacontext

我使用各种元素填充ItemsControl,包括ButtonsComboBox元素。访问和填充元素很简单,但我仍然坚持如何检测并关联Item ItemsControl(或ComboBox)所属的Button。{ / p>

为帮助说明问题,请考虑以下基本用户界面:

Simple Example of A TextBlock, ComboBox, and RadioButton (with ToggleButton Style) inside an ItemsControl

现在,当我使用ComboBoxButton我希望能够将其仅与ItemControl Item相关联时,它就是其中的一部分。但是,目前,如果我在ComboBox中选择ComboBox中的每个ItemsControl中的项目都会反映出此更改。

我可以捕获下面列表框中的SelectedItem,但理想情况下,我希望能够显示SelectedItemItemControl Item来自哪个INotifyProperty。例如, ComboBoxItem1,我的第一个属性 - 来自项目(1)

我严格遵守MVVM原则,因此,我 没有寻找使用代码隐藏的任何解决方案。

TL; DR

  

我知道代码可能变得笨拙。我相信上面的描述足以说明我的问题,但我在下面列出了基本的锅炉板代码,以防它有助于发布答案。 (显然,我已在其他地方实施了ICommand<ItemsControl Width="300" Height="200" ItemsSource="{Binding MyObservableCollection}"> <ItemsControl.ItemTemplate> <DataTemplate> <Border BorderBrush="Black" BorderThickness="2" Margin="10"> <StackPanel Margin="0,10,0,10"> <TextBlock Margin="10,0,0,0" Text="{Binding MyProperty}" FontWeight="Bold"/> <ComboBox Width="270" Text="myBox" ItemsSource="{Binding DataContext.ComboOptions, RelativeSource={RelativeSource AncestorType=ItemsControl}}" DisplayMemberPath="ListItem" SelectedItem="{Binding DataContext.SelectedItem, RelativeSource={RelativeSource AncestorType=Window}}"/> <RadioButton Width ="270" Content="Button1" Command="{Binding DataContext.GetButtonCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" CommandParameter="Button1" Style="{DynamicResource {x:Type ToggleButton}}"/> </StackPanel> </Border> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> ):

MainWindowView.xaml

public class MyComboBoxOptionsViewModel : ObservableObject
{
    private MyComboBoxOptionsModel _myComboBoxOptions = new MyComboBoxOptionsModel();

    public MyComboBoxOptionsViewModel(MyComboBoxOptionsModel _myComboBoxOptions)
    {
        this._myComboBoxOptions = _myComboBoxOptions;
    }

    public string ComboBoxOption
    {
        get { return _myComboBoxOptions.ComboBoxOption; }
        set
        {
            _myComboBoxOptions.ComboBoxOption = value;
            RaisePropertyChangedEvent("ComboBoxOption");
        }
    }
}

MyComboBoxOptionsViewModel.cs

public class MyComboBoxOptionsModel
{
    public string ComboBoxOption { get; set; }
}

MyComboBoxOptionsModel.cs

public class MainWindowViewModel : ObservableObject
{
    private ObservableCollection<string> _messages = new ObservableCollection<string>();
    private ObservableCollection<MyViewModel> _myObservableCollection = new ObservableCollection<MyViewModel>();
    private List<MyComboBoxOptionsViewModel> _comboOptions = new List<MyComboBoxOptionsViewModel>();
    private MyComboBoxOptionsViewModel _selectedItem = new MyComboBoxOptionsViewModel(null);

    public MainWindowViewModel()
    {
        _myObservableCollection.Add(new MyViewModel(new MyModel { MyProperty = "My First Property" }));
        _myObservableCollection.Add(new MyViewModel(new MyModel { MyProperty = "My Second Property" }));

        _comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option1" }));
        _comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option2" }));
        _comboOptions.Add(new MyComboBoxOptionsViewModel(new MyComboBoxOptionsModel { ComboBoxOption = "Option3" }));
    }

    public MyComboBoxOptionsViewModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;
            _messages.Add(_selectedItem.ComboBoxOption);
            RaisePropertyChangedEvent("SelectedItem");
        }
    }

    public List<MyComboBoxOptionsViewModel> ComboOptions
    {
        get { return _comboOptions; }
        set
        {
            if (value != _comboOptions)
            {
                _comboOptions = value;
                RaisePropertyChangedEvent("ComboOptions");
            }
        }
    }

    public ObservableCollection<MyViewModel> MyObservableCollection
    {
        get { return _myObservableCollection; }
        set
        {
            if (value != _myObservableCollection)
            {
                _myObservableCollection = value;
                RaisePropertyChangedEvent("MyObservableCollection");
            }
        }
    }

    public ObservableCollection<string> Messages
    {
        get { return _messages; }
        set
        {
            if (value != _messages)
            {
                _messages = value;
                RaisePropertyChangedEvent("Messages");
            }
        }
    }
}

MainWindowViewModel.cs

{{1}}

1 个答案:

答案 0 :(得分:2)

我正在查看您想要的UI,并认为您基本上需要一个包含项目视图模型集合的主视图模型。

在该项目视图模型中,创建一个命令和一个选定的项目属性,您可以将模板中的项目绑定到组合框和按钮。这为你提供了一个严格的mvvm绑定到组合框值的单个实例和一个由单个按钮实例执行的命令。

然后,对组合框项目的绑定将需要一个显式源作为绑定的一部分,因此您可以从主视图模型挂钩到一个值集合。或者将一个集合添加到您的项目视图模型中,并将它们整齐地保存在一起。

正如你所提到的,你的代码非常详细 - 这很棒 - 但我可能已经错过了其他一些含义。

如果这是对错误问题的回答,请道歉:)