0

いくつかのフィールドを持つビューモデルがあります。

type ViewModel =
    member x.a = [1;2;3]
    member x.b = [4;5;6]
    member x.c = [7]

また、WPFアプリケーションでは、次のようにいくつかのビューを配置します。

<Control.Resources>
                    <DataTemplate x:Key="ItemTempl">
                        <TextBlock Text="{Binding}" />
                    </DataTemplate>

                    <DataTemplate x:Key="SomeTempl">
                        <ListBox ItemsSource="{Binding}"
                                 ItemTemplate="{StaticResource ItemTempl}" />
                    </DataTemplate>
                </Control.Resources>

                <StackPanel>
                    <TabControl x:Name="ListBoxViewPresenter">
                        <TabItem Header="vm.a" Content="{Binding vm.a}" 
                             ContentTemplate="{StaticResource SomeTempl}"/>
                        <TabItem Header="vm.b" Content="{Binding vm.b}" 
                             ContentTemplate="{StaticResource SomeTempl}"/>
                        <TabItem Header="vm.c" Content="{Binding vm.c}" 
                             ContentTemplate="{StaticResource SomeTempl}"/>
                    </TabControl>
                    <ListBox x:Name="ListBoxViewPresenter">
                        <ListBoxItem Content="{Binding vm.a}" 
                                     ContentTemplate="{StaticResource SomeTempl}" />
                        <ListBoxItem Content="{Binding vm.b}" 
                                     ContentTemplate="{StaticResource SomeTempl}" />
                        <ListBoxItem Content="{Binding vm.c}" 
                                     ContentTemplate="{StaticResource SomeTempl}" />
                    </ListBox>
                </StackPanel>

このような動作を実現するにはどうすればよいですか。ListBoxViewPresenterのvm.a/b / cの要素をクリックすると、対応するTabItemでListBoxViewPresenterの同じ要素を選択する必要があります。

UPD:特に私の本当の問題は、元のトピックから変更したことです。

1行、2行...というフィールドを持つViewModelと、selected_schemeという名前のフィールドがあります。xamlの場合:

<TreeViewItem Header="{Binding Path=name}" x:Name="ProjectArea">
                    <TreeViewItem Header="Однониточные планы" Style="{StaticResource MyTreeViewItem}">
                        <ContentPresenter Content="{Binding onelines}" ContentTemplate="{StaticResource SchemeWrapperTemplate}" />
                    </TreeViewItem>
                    <TreeViewItem Header="Двухниточные планы" Style="{StaticResource MyTreeViewItem}">
                        <ContentPresenter Content="{Binding twolines}" ContentTemplate="{StaticResource SchemeWrapperTemplate}" />
                    </TreeViewItem>

そしてデータテンプレート:

            <DataTemplate x:Key="SchemeWrapperTemplate">
            <ListBox ItemsSource="{Binding schemes}" 
                     ItemTemplate="{StaticResource SchemeTemplate}"
                     SelectedItem="{Binding selected_scheme}">
                <ListBox.Style>

プログラムの他の場所:

 <Grid Grid.Row="1">
                    <TextBlock Text="{Binding selected_scheme.path}" />
                </Grid>

また、いくつかのリストボックスをクリックすると、まだSelectedItemsをクリックしても、選択されたアイテムは変更されません。

4

2 に答える 2

2

まず第一に、あなたはあなたのを定義する必要がItemsSourceありTabItemListBoxそれらViewModelにもバインドされています。SelectedItem次に、それらをViewModelのプロパティにバインドできます。

これがコードサンプルです(私は怠惰すぎて個別のViewModelクラスを作成できなかったため、メインウィンドウクラスと混合されていますが、アイデアは得られます...):

コードビハインド:

namespace WpfApplication13
{
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private object _currentlySelectedItem;

        public object CurrentlySelectedItem
        {
            get { return _currentlySelectedItem; }

            set
            {
                _currentlySelectedItem = value;

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("CurrentlySelectedItem"));
                }
            }
        }

        public class MyClass
        {
            public string MyString { get; set; }

            public MyClass(string myString)
            {
                this.MyString = myString;
            }
        }

        private List<MyClass> _myItemsSource = new List<MyClass>
                                               { 
                                                  new MyClass("toto"),
                                                  new MyClass("tata") 
                                               };

        public List<MyClass> MyItemsSource
        {
            get { return _myItemsSource; }
            set { _myItemsSource = value; }
        }

        public object A
        {
            get { return "toto"; }
        }

        public object B
        {
            get { return "tata"; }
        }

        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;
        }
    }
}

xaml:

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <TabControl x:Name="ListBoxViewPresenter"
                        SelectedItem="{Binding CurrentlySelectedItem}"
                        ItemsSource="{Binding MyItemsSource}" />
            <ListBox x:Name="ListBoxViewPresenter2"
                     SelectedItem="{Binding CurrentlySelectedItem}"
                     ItemsSource="{Binding MyItemsSource}" />
        </StackPanel>
    </Grid>
</Window>
于 2012-08-24T11:37:13.667 に答える
1

編集後の新しい回答:

同じオブジェクトを、異なる要素を含む2つの異なるリストのSelectedItemプロパティにバインドすることはあまり意味がありません。アプリケーションを再設計する必要があります。そうしないと、将来のこの奇妙な設計のために多くの問題に直面する可能性があります。

それでも、少しのコード動作でやりたいことを達成できます。ユーザーがリストボックスの1つをクリックすると、他のリストボックスの選択された項目がnullに設定されます。次に、選択がnullから何かに変わるため、最初のリストボックスを再度クリックすると通知されます。

xaml:

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <ListBox x:Name="ListBoxViewPresenter"
                     SelectedItem="{Binding CurrentlySelectedItem}" 
                     ItemsSource="{Binding MyItemsSource}" />
            <ListBox x:Name="ListBoxViewPresenter2"
                     SelectedItem="{Binding CurrentlySelectedItem}" 
                     ItemsSource="{Binding MyItemsSource2}" />
        </StackPanel>
    </Grid>
</Window>

コードビハインド:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Input;
using System.ComponentModel;

namespace WpfApplication13
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        private object _currentlySelectedItem;

        public object CurrentlySelectedItem
        {
            get { return _currentlySelectedItem; }

            set
            {
                _currentlySelectedItem = value;

                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, new PropertyChangedEventArgs("CurrentlySelectedItem"));
                }
            }
        }

        private List<int> _myItemsSource = new List<int> { 1, 2 };

        private List<int> _myItemsSource2 = new List<int> { 3, 4 };

        public List<int> MyItemsSource
        {
            get { return _myItemsSource; }
            set { _myItemsSource = value; }
        }


        public List<int> MyItemsSource2
        {
            get { return _myItemsSource2; }
            set { _myItemsSource2 = value; }
        }

        public MainWindow()
        {
            InitializeComponent();

            this.DataContext = this;

            ListBoxViewPresenter.PreviewMouseDown += ListBoxViewPresenter_PreviewMouseDown;
            ListBoxViewPresenter2.PreviewMouseDown += ListBoxViewPresenter2_PreviewMouseDown;
        }

        void ListBoxViewPresenter_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ListBoxViewPresenter2.SelectedItem = null;
        }

        void ListBoxViewPresenter2_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            ListBoxViewPresenter.SelectedItem = null;
        }
    }
}
于 2012-08-27T15:44:42.477 に答える