gpt4 book ai didi

wpf - 如何在 M-V-VM 设计模式中最好地表示集合中的可选项目?

转载 作者:行者123 更新时间:2023-12-03 10:20:03 25 4
gpt4 key购买 nike

我刚刚开始在重新开发应用程序时探索 M-V-VM 设计模式,并且我在一个一致的主题中运行,我有我需要我的 ViewModel 向 View 公开的集合,其中包含要选择的项目用户。请注意,当我说“已选择”时,我的意思是它们是以某种永久方式选择的,例如在网格控件中使用复选框,而不像在常规列表框控件中那样突出显示。到目前为止,我对如何实现这一点有两种不同的想法,我想知道是否有任何想法关于哪种方式是最好的。

  • 公开两个单独的集合,一个表示可用项目的只读副本,另一个表示包含在第一个集合中的项目的子集,并表示当前选择的可用项目的那些。
  • 通过我的 ViewModel 公开单个集合,但使该集合成为一个专门的集合,以某种方式跟踪选择了集合的哪些项目。可以在 this article 中找到此方法的示例。通过乔什扭曲。

  • 我确实意识到选项 2 实际上只是选项 1 的修改,除了两个集合作为一个单元进行管理。我更感兴趣的是了解哪些方法在 WPF 中的可管理性、性能和有效数据绑定(bind)方面已被证明是成功的。

    我还看到一篇关于 How to Databind to a SelectedItems property in WPF 的文章以及另一个详细说明如何 Sync Multi Select Listbox with ViewModel .在阅读了不同的方法之后,我意识到这可能不是 M-V-VM 从业者达成的共识,但是我希望我可以在不尝试每个方法并进行比较的情况下稍微限制该领域。

    最佳答案

    PRISM MVVM Reference Implementation有一个称为 SynchronizeSelectedItems 的行为,用于 Prism4\MVVM RI\MVVM.Client\Views\MultipleSelectionView.xaml,它将选中的项目与名为 Selections 的 ViewModel 属性同步:

            <ListBox Grid.Column="0" Grid.Row="1" IsTabStop="False" SelectionMode="Multiple"
    ItemsSource="{Binding Question.Range}" Margin="5">

    <ListBox.ItemContainerStyle>
    <!-- Custom style to show the multi-selection list box as a collection of check boxes -->
    <Style TargetType="ListBoxItem">
    <Setter Property="Template">
    <Setter.Value>
    <ControlTemplate TargetType="ListBoxItem">
    <Grid Background="Transparent">
    <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
    IsHitTestVisible="False" IsTabStop="True"
    AutomationProperties.AutomationId="CheckBoxAutomationId">
    <ContentPresenter/>
    </CheckBox>
    </Grid>
    </ControlTemplate>
    </Setter.Value>
    </Setter>
    </Style>
    </ListBox.ItemContainerStyle>
    <i:Interaction.Behaviors>
    <!-- Custom behavior that synchronizes the selected items with the view models collection -->
    <Behaviors:SynchronizeSelectedItems Selections="{Binding Selections}"/>
    </i:Interaction.Behaviors>
    </ListBox>

    转至 http://compositewpf.codeplex.com/并捕获它或使用它:
    //===================================================================================
    // Microsoft patterns & practices
    // Composite Application Guidance for Windows Presentation Foundation and Silverlight
    //===================================================================================
    // Copyright (c) Microsoft Corporation. All rights reserved.
    // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
    // OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
    // LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
    // FITNESS FOR A PARTICULAR PURPOSE.
    //===================================================================================
    // The example companies, organizations, products, domain names,
    // e-mail addresses, logos, people, places, and events depicted
    // herein are fictitious. No association with any real company,
    // organization, product, domain name, email address, logo, person,
    // places, or events is intended or should be inferred.
    //===================================================================================
    using System;
    using System.Collections;
    using System.Collections.Specialized;
    using System.Diagnostics.CodeAnalysis;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Interactivity;

    namespace MVVM.Client.Infrastructure.Behaviors
    {
    /// <summary>
    /// Custom behavior that synchronizes the list in <see cref="ListBox.SelectedItems"/> with a collection.
    /// </summary>
    /// <remarks>
    /// This behavior uses a weak event handler to listen for changes on the synchronized collection.
    /// </remarks>
    public class SynchronizeSelectedItems : Behavior<ListBox>
    {
    public static readonly DependencyProperty SelectionsProperty =
    DependencyProperty.Register(
    "Selections",
    typeof(IList),
    typeof(SynchronizeSelectedItems),
    new PropertyMetadata(null, OnSelectionsPropertyChanged));

    private bool updating;
    private WeakEventHandler<SynchronizeSelectedItems, object, NotifyCollectionChangedEventArgs> currentWeakHandler;

    [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly",
    Justification = "Dependency property")]
    public IList Selections
    {
    get { return (IList)this.GetValue(SelectionsProperty); }
    set { this.SetValue(SelectionsProperty, value); }
    }

    protected override void OnAttached()
    {
    base.OnAttached();

    this.AssociatedObject.SelectionChanged += this.OnSelectedItemsChanged;
    this.UpdateSelectedItems();
    }

    protected override void OnDetaching()
    {
    this.AssociatedObject.SelectionChanged += this.OnSelectedItemsChanged;

    base.OnDetaching();
    }

    private static void OnSelectionsPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
    var behavior = d as SynchronizeSelectedItems;

    if (behavior != null)
    {
    if (behavior.currentWeakHandler != null)
    {
    behavior.currentWeakHandler.Detach();
    behavior.currentWeakHandler = null;
    }

    if (e.NewValue != null)
    {
    var notifyCollectionChanged = e.NewValue as INotifyCollectionChanged;
    if (notifyCollectionChanged != null)
    {
    behavior.currentWeakHandler =
    new WeakEventHandler<SynchronizeSelectedItems, object, NotifyCollectionChangedEventArgs>(
    behavior,
    (instance, sender, args) => instance.OnSelectionsCollectionChanged(sender, args),
    (listener) => notifyCollectionChanged.CollectionChanged -= listener.OnEvent);
    notifyCollectionChanged.CollectionChanged += behavior.currentWeakHandler.OnEvent;
    }

    behavior.UpdateSelectedItems();
    }
    }
    }

    private void OnSelectedItemsChanged(object sender, SelectionChangedEventArgs e)
    {
    this.UpdateSelections(e);
    }

    private void UpdateSelections(SelectionChangedEventArgs e)
    {
    this.ExecuteIfNotUpdating(
    () =>
    {
    if (this.Selections != null)
    {
    foreach (var item in e.AddedItems)
    {
    this.Selections.Add(item);
    }

    foreach (var item in e.RemovedItems)
    {
    this.Selections.Remove(item);
    }
    }
    });
    }

    private void OnSelectionsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
    this.UpdateSelectedItems();
    }

    private void UpdateSelectedItems()
    {
    this.ExecuteIfNotUpdating(
    () =>
    {
    if (this.AssociatedObject != null)
    {
    this.AssociatedObject.SelectedItems.Clear();
    foreach (var item in this.Selections ?? new object[0])
    {
    this.AssociatedObject.SelectedItems.Add(item);
    }
    }
    });
    }

    private void ExecuteIfNotUpdating(Action execute)
    {
    if (!this.updating)
    {
    try
    {
    this.updating = true;
    execute();
    }
    finally
    {
    this.updating = false;
    }
    }
    }
    }
    }

    关于wpf - 如何在 M-V-VM 设计模式中最好地表示集合中的可选项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1235772/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com