2013-04-10 18 views
0

我特別需要使用System.Drawing.Graphics作爲圖像控件的ImageSource。該圖形將通過滑塊進行更新,該滑塊的值將數據綁定到作爲構建圖形模型的對象。在滑塊和對象之間進行簡單的數據綁定以更新WPF中的圖形

我已經設置了什麼,我想完成一個最小的工作版本,並創造了儘可能多的「綁定基礎設施」盡我所能,但已經停止了事情開始讓我迷惑。我的代碼中有剛的主窗口(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和01之間的綁定,所以當我移動滑塊時圖像更新,這將讓我去!

+0

爲什麼你不在MainWindow類中創建一個'Radius'屬性,並將Slider的值綁定到該屬性? – Clemens 2013-04-10 21:15:26

+0

@Clemens這會違反模型/視圖分離,我認爲。我需要的圖紙,以反映更新充當模特,因爲會有我的程序等元素將引用這個對象,應該是不知道該視圖的對象。 – heltonbiker 2013-04-10 23:10:34

回答

1

如果你簡單地畫一個橢圓,我建議你結合這兩個滑塊的價值和橢圓對象存儲有關的值的對象。您可以在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> 

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

+1用於引入Converter的概念,從對象中獲取ImageSource,保持數據綁定「更清潔」。我明天會試試這個,非常感謝你! – heltonbiker 2013-04-11 03:47:09