0

我特别需要System.Drawing.Graphics用作 Image 控件的 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>

MainWindow 代码隐藏:

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();
        }

    }
}

如果有人能建议我应该做些什么来实现和之间的绑定SizeSliderradius_instance.Value那么当我移动滑块时图像会更新,那会让我继续前进!

4

1 回答 1

1

如果您只是绘制一个椭圆,我建议将滑块的值和 Ellipse 对象绑定到存储相关值的对象。您可以在http://msdn.microsoft.com/en-us/library/ms747393.aspx上查看有关使用 Wpf 绘图的更多信息。

<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>

值转换器:

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 回答