0

System.Drawing.GraphicsImage コントロールの ImageSource として使用する特定の必要があります。そのグラフィックスは、スライダーによって更新されます。スライダーの値は、図面を作成するモデルとして機能するオブジェクトにデータ バインドされます。

達成したいことの最小限の作業バージョンをセットアップし、できる限り多くの「結合インフラストラクチャ」を作成しましたが、混乱し始めたところで停止しました。私のコードには、MainWindow (XAML とコード ビハインド) と Radius クラスだけがあります。

メインウィンドウ:

<Window x:Class="MinimalUpdateableDrawing.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        WindowState="Maximized">
    <DockPanel>
        <Slider x:Name="SizeSlider"  DockPanel.Dock="Bottom" />
        <Image x:Name="figure" Width="800" Height="600" />
    </DockPanel>
</Window>

メインウィンドウの分離コード:

using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows;
using System.Windows.Media.Imaging;

namespace MinimalUpdateableDrawing {
    public partial class MainWindow : Window {

        Radius radius_instance;

        public MainWindow() {
            InitializeComponent();

            radius_instance = new Radius();

            this.Loaded +=new RoutedEventHandler(DrawCircle);
        }

        void DrawCircle(object sender, RoutedEventArgs e) {

            int radius = radius_instance.Value;

            using (var bmp = new Bitmap((int)figure.Width, (int)figure.Height)) {
                using (var g = Graphics.FromImage(bmp)) {
                    g.FillEllipse(System.Drawing.Brushes.Blue,
                                  (int)figure.Width/2-radius,
                                  (int)figure.Height/2-radius,
                                  radius*2, radius*2);
                }

                using(MemoryStream ms = new MemoryStream()) {
                    bmp.Save(ms, ImageFormat.Bmp);
                    ms.Position = 0;
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = ms;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();
                    figure.Source = bitmapImage;
                }
            }
        }
    }
}

半径クラス:

using System;
using System.ComponentModel;

namespace MinimalUpdateableDrawing
{
    class Radius : INotifyPropertyChanged {

        int _value = 100;

        public int Value {
            get { return _value; }
            set {
                _value = value;
                OnPropertyChanged("Value");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string p) {
            throw new NotImplementedException();
        }

    }
}

SizeSliderとの間のバインディングを実装するために何をすべきかを誰かが提案できればradius_instance.Value、スライダーを動かしたときに画像が更新されるようになります。

4

1 に答える 1

1

単純に楕円を描く場合は、スライダーの値と Ellipse オブジェクトの両方を、問題の値を格納するオブジェクトにバインドすることをお勧めします。Wpf を使用した描画の詳細については、http://msdn.microsoft.com/en-us/library/ms747393.aspx を参照してください

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

    <Ellipse Height="{Binding Radius}" Width="{Binding Radius}" HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" />
    <Slider Value="{Binding Radius}" Grid.Row="1" Minimum="0" Maximum="200" />
</Grid>

そうは言っても、描画がより複雑な場合は、IValueConverter を使用して、使用できる描画に値を適合させることを検討することをお勧めします。たとえば、次のようになります。

<Window x:Class="WpfApplication1.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WpfApplication1"
            Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:EllipseConverter x:Key="EllipseConverter" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Image Source="{Binding Radius, Converter={StaticResource EllipseConverter}}" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None" />
        <Slider Value="{Binding Radius}" Grid.Row="1" Minimum="0" Maximum="200" />
    </Grid>
</Window>

IValueConverter:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace WpfApplication1
{
    class EllipseConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value == null) return null;

            int radius = (int)value;
            int diameter = radius * 2;

            using (var bmp = new System.Drawing.Bitmap(diameter, diameter))
            {
                using (var g = Graphics.FromImage(bmp))
                {
                    g.FillEllipse(System.Drawing.Brushes.Blue,
                                  0,
                                  0,
                                  diameter,
                                  diameter);
                }

                using (MemoryStream ms = new MemoryStream())
                {
                    bmp.Save(ms, ImageFormat.Bmp);
                    ms.Position = 0;
                    BitmapImage bitmapImage = new BitmapImage();
                    bitmapImage.BeginInit();
                    bitmapImage.StreamSource = ms;
                    bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                    bitmapImage.EndInit();

                    return bitmapImage;
                }
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}
于 2013-04-11T00:36:52.440 に答える