2

假设我有一个大的位集(类无关紧要,可以是 bool[100]),我有 10x10 的黑色和白色矩形,我想将它们绑定到我的位集中的每个单独的位。

我也不想在单个位更改时强制完全重绘(有一些解决方案可能导致这种行为),而只是对该特定矩形进行一次重绘。

关于我的实际实现的任何其他细节都无关紧要,我可以使用任何最适合存储这些位的类(ObservableCollection,其他,你说的)。

我更喜欢最优雅的解决方案,我也不想用 100 个属性来放大视图模型......和巨大的案例方法。

4

1 回答 1

1

这是一个测试解决方案的有趣问题。:)

这是我想出的。单击播放按钮以观看颜色随机化。

看法:

<UserControl
    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:vm="clr-namespace:Samples.ViewModels"
    xmlns:toolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" x:Class="Samples.BitsetView"
    mc:Ignorable="d"
    d:DesignHeight="400" d:DesignWidth="500">

    <UserControl.Resources>
        <vm:BitsetViewModel x:Key="vm" />
        <ItemsPanelTemplate x:Key="ItemsPanelTemplate">
            <toolkit:WrapPanel />
        </ItemsPanelTemplate>
        <DataTemplate x:Key="ItemTemplate">
            <Rectangle Width="10" Height="10" Fill="{Binding Brush}"/>
        </DataTemplate>
    </UserControl.Resources>

    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource vm}" Width="500" Height="400">
        <ItemsControl Margin="0" ItemsSource="{Binding Bitset}" ItemsPanel="{StaticResource ItemsPanelTemplate}" ItemTemplate="{StaticResource ItemTemplate}"/>
        <Button Content="{Binding Action}" Height="23" Width="40" HorizontalAlignment="Center" VerticalAlignment="Bottom">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <ei:CallMethodAction TargetObject="{Binding}" MethodName="Play"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
    </Grid>
</UserControl>

和视图模型:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Media;
using System.Windows.Threading;

namespace Samples.ViewModels
{
    public class BitsetViewModel
    {
        private List<BitsetItem> _bitset = new List<BitsetItem>();
        private Random _rand = new Random();
        private DispatcherTimer _timer = new DispatcherTimer();

        public BitsetViewModel()
        {
            _timer.Interval = TimeSpan.FromMilliseconds(1);
            _timer.Tick += new EventHandler(_timer_Tick);

            for (int i = 0; i < 2000; i++)
            {
                var color = _rand.Next(0, 5);
                _bitset.Add(new BitsetItem() { Color = color == 1 ? Colors.Black : Colors.White });
            }
        }

        void _timer_Tick(object sender, EventArgs e)
        {
            var bit = _rand.Next(0, 1999);
            _bitset[bit].Color = _bitset[bit].Color == Colors.White ? Colors.Black : Colors.White;
        }

        public IEnumerable<BitsetItem> Bitset
        {
            get {return _bitset;}
        }

        public string Action
        {
            get { return _timer.IsEnabled ? "Stop" : "Play"; }
        }

        public void Play()
        {
            if (_timer.IsEnabled)
                _timer.Stop();
            else
                _timer.Start();
        }
    }

    public class BitsetItem : INotifyPropertyChanged
    {
        private Color _color = Colors.White;
        private SolidColorBrush _brush = new SolidColorBrush();

        public Color Color
        {
            get { return _color; }
            set
            {
                _color = value;
                _brush = new SolidColorBrush(Color);
                RaisePropertyChanged("Color");
                RaisePropertyChanged("Brush");
            }
        }

        public SolidColorBrush Brush
        {
            get { return _brush; }
            set
            {
                _brush = value;
                RaisePropertyChanged("Brush");
            }
        }

        private void RaisePropertyChanged(string name)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}
于 2011-09-20T18:08:19.523 回答