WPF MVVM层次结构选择项 [英] WPF MVVM hierarchy selected item

查看:71
本文介绍了WPF MVVM层次结构选择项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我当前正在使用ListBoxes实现显示层次结构的应用程序(请不要建议使用TreeView,需要使用ListBoxes).

在以下文章中看起来像> WPF的CollectionViewSource(带有源代码).

课程:

public class Mountains : ObservableCollection<Mountain>
{
    public ObservableCollection<Lift> Lifts { get; }

    public string Name { get; }
}

public class Lift
{
    public ObservableCollection<string> Runs { get; }
}

该示例使用CollectionViewSource实例(请参阅XAML)来简化设计. Mountains类的实例是窗口的DataContext.


问题是:我希望Mountains类具有SelectedRun属性,并且应该将其设置为当前选择的运行.

public class Mountains : ObservableCollection<Mountain>
{
    public ObservableCollection<Lift> Lifts { get; }

    public string Name { get; }

    public string SelectedRun { get; set; }
}

也许我错过了一些基本原理,但是我该如何实现呢?

解决方案

您可能想阅读有关在绑定中使用'/'的信息.请参见此 MSDN文章中的当前项目指针"部分.. >

这是我的解决方法:

Xaml

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBlock Margin="5" Grid.Row="0" Grid.Column="0" Text="Mountains"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="1" Text="Lifts"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="2" Text="Runs"/>

    <ListBox Grid.Row="1" Grid.Column="0" Margin="5" 
             ItemsSource="{Binding Mountains}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True" />

    <ListBox Grid.Row="1" Grid.Column="1" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True"/>

    <ListBox Grid.Row="1" Grid.Column="2" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts/Runs}" 
             IsSynchronizedWithCurrentItem="True" 
             SelectedItem="{Binding SelectedRun}"/>
</Grid>

C#(请注意,除非将更改属性,而不仅仅是选择属性,否则您无需实现INotifyPropertyChanged)

public class MountainsViewModel
{
    public MountainsViewModel()
    {
        Mountains = new ObservableCollection<Mountain>
                        {
                            new Mountain
                                {
                                    Name = "Whistler",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift
                                                        {
                                                            Name = "Big Red",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall",
                                                                           "Fisheye",
                                                                           "Jimmy's"
                                                                       }
                                                        },
                                                    new Lift
                                                        {
                                                            Name = "Garbanzo",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall1",
                                                                           "Fisheye1",
                                                                           "Jimmy's1"
                                                                       }
                                                        },
                                                    new Lift {Name = "Orange"},
                                                }

                                },
                            new Mountain
                                {
                                    Name = "Stevens",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift {Name = "One"},
                                                    new Lift {Name = "Two"},
                                                    new Lift {Name = "Three"},
                                                }

                                },
                            new Mountain {Name = "Crystal"},
                        };
    }

    public string Name { get; set; }
    private string _selectedRun;
    public string SelectedRun
    {
        get { return _selectedRun; }
        set
        {
            Debug.WriteLine(value);
            _selectedRun = value;
        }
    }

    public ObservableCollection<Mountain> Mountains { get; set; }
}

public class Mountain
{
    public string Name { get; set; }

    public ObservableCollection<Lift> Lifts { get; set; }
}

public class Lift
{
    public string Name { get; set; }

    public ObservableCollection<string> Runs { get; set; }
}

I am currently implementing the application that displays hierarchy using ListBoxes (please do not suggest using TreeView, ListBoxes are needed).

It looks like that in the article: WPF’s CollectionViewSource (with source code).

Classes:

public class Mountains : ObservableCollection<Mountain>
{
    public ObservableCollection<Lift> Lifts { get; }

    public string Name { get; }
}

public class Lift
{
    public ObservableCollection<string> Runs { get; }
}

The example uses CollectionViewSource instances (see XAML) to simplify the design. An instance of Mountains class is the DataContext for the window.


The problem is: I would like that the Mountains class to have SelectedRun property and it should be set to currently selected run.

public class Mountains : ObservableCollection<Mountain>
{
    public ObservableCollection<Lift> Lifts { get; }

    public string Name { get; }

    public string SelectedRun { get; set; }
}

Maybe I've missed something basic principle, but how can I achieve this?

解决方案

You may want to read about the use of '/' in bindings. See the section 'current item pointers' on this MSDN article.

Here's my solution:

Xaml

    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <TextBlock Margin="5" Grid.Row="0" Grid.Column="0" Text="Mountains"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="1" Text="Lifts"/>
    <TextBlock Margin="5" Grid.Row="0" Grid.Column="2" Text="Runs"/>

    <ListBox Grid.Row="1" Grid.Column="0" Margin="5" 
             ItemsSource="{Binding Mountains}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True" />

    <ListBox Grid.Row="1" Grid.Column="1" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts}" DisplayMemberPath="Name" 
             IsSynchronizedWithCurrentItem="True"/>

    <ListBox Grid.Row="1" Grid.Column="2" Margin="5" 
             ItemsSource="{Binding Mountains/Lifts/Runs}" 
             IsSynchronizedWithCurrentItem="True" 
             SelectedItem="{Binding SelectedRun}"/>
</Grid>

C# (note, you don't need to implement INotifyPropertyChanged unless the properties will be changed and not just selected)

public class MountainsViewModel
{
    public MountainsViewModel()
    {
        Mountains = new ObservableCollection<Mountain>
                        {
                            new Mountain
                                {
                                    Name = "Whistler",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift
                                                        {
                                                            Name = "Big Red",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall",
                                                                           "Fisheye",
                                                                           "Jimmy's"
                                                                       }
                                                        },
                                                    new Lift
                                                        {
                                                            Name = "Garbanzo",
                                                            Runs = new ObservableCollection<string>
                                                                       {
                                                                           "Headwall1",
                                                                           "Fisheye1",
                                                                           "Jimmy's1"
                                                                       }
                                                        },
                                                    new Lift {Name = "Orange"},
                                                }

                                },
                            new Mountain
                                {
                                    Name = "Stevens",
                                    Lifts = new ObservableCollection<Lift>
                                                {
                                                    new Lift {Name = "One"},
                                                    new Lift {Name = "Two"},
                                                    new Lift {Name = "Three"},
                                                }

                                },
                            new Mountain {Name = "Crystal"},
                        };
    }

    public string Name { get; set; }
    private string _selectedRun;
    public string SelectedRun
    {
        get { return _selectedRun; }
        set
        {
            Debug.WriteLine(value);
            _selectedRun = value;
        }
    }

    public ObservableCollection<Mountain> Mountains { get; set; }
}

public class Mountain
{
    public string Name { get; set; }

    public ObservableCollection<Lift> Lifts { get; set; }
}

public class Lift
{
    public string Name { get; set; }

    public ObservableCollection<string> Runs { get; set; }
}

这篇关于WPF MVVM层次结构选择项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆