不使用 Messenger 或 EventAggregator 的 ItemsControl 中的 Items 之间的通信

Communication between Items in ItemsControl without using Messenger or EventAggregator

在不使用 Messenger 或 EventAggregator 的情况下,ItemsControl 中的 Bindings 中的 Items 如何相互通信。下面是一个简化但完整的案例。我在 ItemsControl 中有两个关联的项目。 UpdateTheSecondItemFromTheFirstItem() 可以通过使用 prism 中的 EventAggregator(messenger) 来完成。但我想知道是否有更直接的解决方案可以在不使用 Messenger 的情况下实现这一目标。 主窗口:

    <Window x:Class="WpfApp2.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:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
  <ItemsControl ItemsSource="{Binding MyItems}">
       <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
               <StackPanel Orientation="Vertical">
              </StackPanel>
          </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
         <DataTemplate DataType="MyType">
            <Grid>
                <Slider Value="{Binding MyNum}" Minimum="0" Maximum="100"></Slider>
            </Grid>
         </DataTemplate>
        </ItemsControl.ItemTemplate>
  </ItemsControl>
</Grid>

我的类型

   using Prism.Mvvm;

namespace WpfApp2
{
    public class MyType : BindableBase
    {
        private bool _isFirstItem=false;

        private int _myVar;

        public int MyVar
        {
            get { return _myVar; }
            set
            {
                if (Equals(_myVar, value)) return;
                SetProperty(ref _myVar, value);
            }
        }

        public MyType(bool isFirst)
        {
            _isFirstItem = isFirst;
            MyVar = 0;
        }
    }
}

MainWindowViewModel

    using Prism.Mvvm;
using System.Collections.ObjectModel;

namespace WpfApp2
{
    public class MainWindowViewModel:BindableBase
    {
        private ObservableCollection<MyType> _myItems = new ObservableCollection<MyType>();

        public ObservableCollection<MyType> MyItems
        {
            get { return _myItems; }
            set
            {
                if (Equals(_myItems, value)) return;
                SetProperty(ref _myItems, value);
                if(_isFirstItem) UpdateTheSecondItemFromTheFirstItem();
            }
        }

        private void UpdateTheSecondItemFromTheFirstItem(){

        }

        public MainWindowViewModel()
        {
            MyType[] MyTypeArr =
            {
                new MyType(true),
                new MyType(false)
            };
            MyItems.AddRange(MyTypeArr);
        }
    }
}

找到解决方案,只需要使用 ref,这与 C++ 中的指针完全一样:

MainWindowViewModel:

        public MainWindowViewModel()
    {
        MyType Type1 = new MyType();
        MyType Type2 = new MyType();

        MyItems.Add(Type1);
        MyItems.Add(Type2);

        Type1.SetPair(ref Type2);
    }

MyType.cs:

   using Prism.Mvvm;

namespace WpfApp2
{
    public class MyType : BindableBase
    {
        private int _myVar;

        public int MyVar
        {
            get { return _myVar; }
            set
            {
                if (Equals(_myVar, value)) return;
                SetProperty(ref _myVar, value);
                if (MyPair!=null)
                {
                    MyPair.MyVar = value;
                }
            }
        }

        public MyType()
        {
            MyVar = 0;
        }

        MyType MyPair { get; set; }

        public void SetPair(ref MyType pair)
        {
            MyPair = pair;
        }

        public MyType GetPair()
        {
            return MyPair;
        }
    }
}    

现在,拖动滑块时,第二个滑块会随着第一个滑块移动。