WPF MvvmLight Register,Send,Unregister

复制代码
//Register
Messenger.Default.Register<object>(this, "ShowItemsCountToken", ShowItemsCount);

//Send
Messenger.Default.Send<object>(obj, "ShowItemsCountToken");

//Unregister
Messenger.Default.Unregister<object>(this,"CountToken");


//Action<object> action
 public void ShowItemsCount(object obj)
 {
     var lbx = obj as ListBox;
     if(lbx!=null && lbx.Items!=null)
     {
         var items = lbx.Items.Cast<Book>()?.ToList();
         if(items!=null &&items.Any())
         {
             MessageBox.Show($"Count:{items.Count}");
         }
     }
 }
复制代码

 

 

In Nuget search MvvmLight and install

 

复制代码
    //
    // Summary:
    //     Registers a recipient for a type of message TMessage. The action parameter will
    //     be executed when a corresponding message is sent. See the receiveDerivedMessagesToo
    //     parameter for details on how messages deriving from TMessage (or, if TMessage
    //     is an interface, messages implementing TMessage) can be received too.
    //
    //     Registering a recipient does not create a hard reference to it, so if this recipient
    //     is deleted, no memory leak is caused.
    //
    // Parameters:
    //   recipient:
    //     The recipient that will receive the messages.
    //
    //   token:
    //     A token for a messaging channel. If a recipient registers using a token, and
    //     a sender sends a message using the same token, then this message will be delivered
    //     to the recipient. Other recipients who did not use a token when registering (or
    //     who used a different token) will not get the message. Similarly, messages sent
    //     without any token, or with a different token, will not be delivered to that recipient.
    //
    //
    //   action:
    //     The action that will be executed when a message of type TMessage is sent.
    //
    //   keepTargetAlive:
    //     If true, the target of the Action will be kept as a hard reference, which might
    //     cause a memory leak. You should only set this parameter to true if the action
    //     is using closures. See http://galasoft.ch/s/mvvmweakaction.
    //
    // Type parameters:
    //   TMessage:
    //     The type of message that the recipient registers for.
    void Register<TMessage>(object recipient, object token, Action<TMessage> action, bool keepTargetAlive = false);





//
// Summary:
//     Sends a message to registered recipients. The message will reach only recipients
//     that registered for this message type using one of the Register methods, and
//     that are of the targetType.
//
// Parameters:
//   message:
//     The message to send to registered recipients.
//
//   token:
//     A token for a messaging channel. If a recipient registers using a token, and
//     a sender sends a message using the same token, then this message will be delivered
//     to the recipient. Other recipients who did not use a token when registering (or
//     who used a different token) will not get the message. Similarly, messages sent
//     without any token, or with a different token, will not be delivered to that recipient.
//
//
// Type parameters:
//   TMessage:
//     The type of message that will be sent.
void Send<TMessage>(TMessage message, object token);



//
// Summary:
//     Unregisters a message recipient for a given type of messages only and for a given
//     token. After this method is executed, the recipient will not receive messages
//     of type TMessage anymore with the given token, but will still receive other message
//     types or messages with other tokens (if it registered for them previously).
//
// Parameters:
//   recipient:
//     The recipient that must be unregistered.
//
//   token:
//     The token for which the recipient must be unregistered.
//
// Type parameters:
//   TMessage:
//     The type of messages that the recipient wants to unregister from.
void Unregister<TMessage>(object recipient, object token);
复制代码

 

 

Full code

复制代码
<Window x:Class="WpfApp379.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:local="clr-namespace:WpfApp379" 
        mc:Ignorable="d" WindowState="Maximized"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:BookVM/>
    </Window.DataContext>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ToolBar Grid.Row="0">
            <Button Content="Load" Command="{Binding LoadCmd}" Width="100"/>
        </ToolBar>
        <ListBox x:Name="lbx" Grid.Row="1" BorderBrush="Blue" BorderThickness="5"
                 VirtualizingPanel.CacheLength="100" 
                 VirtualizingPanel.CacheLengthUnit="Item"
                 VirtualizingPanel.IsContainerVirtualizable="True"
                 VirtualizingPanel.IsVirtualizing="True"
                 VirtualizingPanel.VirtualizationMode="Recycling"
                 ItemsSource="{Binding BooksCollection,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
            <ListBox.ContextMenu>
                <ContextMenu>
                    <MenuItem Header="Export NewtonSoftJson"  
                              FontSize="50" 
                              Foreground="Red"
                              Command="{Binding ExportNewtonJsonCmd}"
                              CommandParameter="{Binding RelativeSource={RelativeSource 
                              Mode=FindAncestor,AncestorType={x:Type ContextMenu}},Path=PlacementTarget}"/>
                    <MenuItem Header="Export BinaryFormatter"
                              FontSize="50"
                              Foreground="Red"
                              Command="{Binding ExportBinaryFormatterCmd}"
                              CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type ContextMenu}},Path=PlacementTarget}"/>
                    <MenuItem Header="Show ItemsCount"
                              FontSize="50"
                              Foreground="Red"
                              Command="{Binding ShowItemcCountCmd}"
                              CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                        AncestorType={x:Type ContextMenu}},Path=PlacementTarget}"/>
                </ContextMenu>
            </ListBox.ContextMenu>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Image Source="{Binding ImgUrl}"
                               Width="{Binding ActualWidth,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"
                               Height="{Binding ActualHeight,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Window}}}"/>
                        <TextBlock Text="{Binding Name}" FontSize="150" Foreground="Red"
                                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>


//cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;
using Microsoft.Win32;
using Newtonsoft.Json;
using System.Runtime.Serialization.Formatters.Binary;
using GalaSoft.MvvmLight.Messaging;

namespace WpfApp379
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }

    public class BookVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        private ObservableCollection<Book> booksCollection;
        public ObservableCollection<Book> BooksCollection
        {
            get
            {
                return booksCollection;
            }
            set
            {
                if (value != booksCollection)
                {
                    booksCollection = value;
                    OnPropertyChanged(nameof(BooksCollection));
                }
            }
        }


        public BookVM()
        {
            InitCmds();
            InitData();
        }

        ~BookVM()
        {
            Messenger.Default.Unregister<object>(this,"CountToken");
        }

        public DelCmd LoadCmd { get; set; }
        public DelCmd ExportNewtonJsonCmd { get; set; }
        public DelCmd ExportBinaryFormatterCmd { get; set; }
        public DelCmd ShowItemcCountCmd { get; set; }
        private void InitCmds()
        {
            LoadCmd = new DelCmd(LoadCmdExecuted);
            ExportNewtonJsonCmd = new DelCmd(ExportNewtonJsonCmdExecuted);
            ExportBinaryFormatterCmd = new DelCmd(ExportBinaryFormatterCmdExecuted);
            ShowItemcCountCmd = new DelCmd(ShowItemcCountCmdExecuted);
            RegisterCommands();
        }

        private void ShowItemcCountCmdExecuted(object obj)
        {
            Messenger.Default.Send<object>(obj, "ShowItemsCountToken");
        }

        private void RegisterCommands()
        {
            Messenger.Default.Register<object>(this, "ShowItemsCountToken", ShowItemsCount);
        }

        public void ShowItemsCount(object obj)
        {
            var lbx = obj as ListBox;
            if(lbx!=null && lbx.Items!=null)
            {
                var items = lbx.Items.Cast<Book>()?.ToList();
                if(items!=null &&items.Any())
                {
                    MessageBox.Show($"Count:{items.Count}");
                }
            }
        }

        private void ExportBinaryFormatterCmdExecuted(object obj)
        {
            var lbx = obj as ListBox;
            if (lbx != null)
            {
                var items = lbx.Items.Cast<Book>()?.ToList();
                if (items != null && items.Any())
                {
                    SaveFileDialog dialog = new SaveFileDialog();
                    dialog.Filter = "All Files|*.*|Json Files|*.json";
                    dialog.FileName = $"Bin{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString("N")}.bin";
                    if (dialog.ShowDialog() == true)
                    {
                        using (FileStream fs = new FileStream(dialog.FileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                        {
                            BinaryFormatter binFormatter = new BinaryFormatter();
                            binFormatter.Serialize(fs, items);
                        }
                        MessageBox.Show($"Binary Serialized in {dialog.FileName}", "Binary Serialize", MessageBoxButton.OK);
                    }
                }
            }
        }

        private void ExportNewtonJsonCmdExecuted(object obj)
        {
            var lbx = obj as ListBox;
            if(lbx!=null)
            {
                var items = lbx.Items.Cast<Book>()?.ToList();
                if(items!=null && items.Any())
                {
                    SaveFileDialog dialog = new SaveFileDialog();
                    dialog.Filter = "All Files|*.*|Json Files|*.json";
                    dialog.FileName = $"Json{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString("N")}.json";
                    if(dialog.ShowDialog()==true)
                    {
                        string jsonStr=JsonConvert.SerializeObject(items,Formatting.Indented);
                        File.AppendAllText(dialog.FileName, jsonStr);
                        MessageBox.Show($"Saved in {dialog.FileName}", "Saved Json", MessageBoxButton.OK);
                    }
                }
            }
        }

        private void LoadCmdExecuted(object obj)
        {
            InitData(); 
        }

        private void InitData()
        {
            var imgsList = Directory.GetFiles("../../Images");
            if (imgsList != null && imgsList.Count() > 0)
            {
                int imgsCount = imgsList.Count();
                BooksCollection = new ObservableCollection<Book>();
                for (int i = 0; i < 1000000; i++)
                {
                    BooksCollection.Add(new Book()
                    {
                        Id = i + 1,
                        Name = $"Name_{i + 1}",
                        Title = $"Title_{i + 1}",
                        Topic = $"Topic_{i + 1}",
                        ImgUrl = imgsList[i % imgsCount]
                    });
                }
            }
        }
    }

    public class DelCmd : ICommand
    {
        public event EventHandler CanExecuteChanged
        {
            add
            {
                CommandManager.RequerySuggested += value;
            }
            remove
            {
                CommandManager.RequerySuggested -= value;
            }
        }

        private Action<object> execute;
        private Predicate<object> canExecute;

        public DelCmd(Action<object> executeValue, Predicate<object> canExecuteValue)
        {
            execute = executeValue;
            canExecute = canExecuteValue;
        }

        public DelCmd(Action<object> executeValue) : this(executeValue, null)
        {
        }

        public bool CanExecute(object parameter)
        {
            if (canExecute == null)
            {
                return true;
            }
            return canExecute(parameter);
        }

        public void Execute(object parameter)
        {
            execute(parameter);
        }
    }


    [Serializable]
    public class Book
    {
        public int Id { get; set; }

        public string ImgUrl { get; set; }
        public string Name { get; set; }

        public string Title { get; set; }

        public string Topic { get; set; }
    }
}
复制代码

 

posted @   FredGrit  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
历史上的今天:
2019-09-18 wpf button style IsMouseOver
点击右上角即可分享
微信分享提示