簡體   English   中英

我如何將此方法從Winforms轉換為WPF?

[英]How would I go about translating this method from Winforms to WPF?

我有一個簡單的程序,可以根據一系列數字創建一系列PNG圖像,即; 我遍歷每個數字,並以各種大小創建該數字的png圖像。 以下是我用來創建圖像的空白。

private void CreatePNG(int number, string location, int width, int height)
        {
            string filename = number.ToString() + "-" + width.ToString() + "x" + height.ToString() + ".png";            
            Bitmap b = new Bitmap(width, height);

            Graphics g = Graphics.FromImage((System.Drawing.Image)b);
            g.FillRectangle(Brushes.White, 0f, 0f, width, height);

            StringFormat f = new StringFormat();
            f.Alignment = StringAlignment.Center;
            f.LineAlignment = StringAlignment.Center;
            g.DrawString(number.ToString(), new Font("Helvetica", 55), Brushes.Black, new RectangleF(0, 0, width, height), f);
            b.Save(location + "\\" + filename, ImageFormat.Png);    
        }

我想要做的是將此void轉換為與WPF一起使用。 我目前對WPF沒有經驗,因此我的noobie問題。

目標框架是4.0

非常感謝幫助。

System.Drawing是WinForms NOT WPF的一部分

首先,我想澄清一個誤解。

System.Drawing基於Win32的GDI +,實際上是WinForms的一個組件。 WPF不是基於它構建的,Silverlight和其他平台的WPF端口可能永遠不會包含它,並且System.Drawing(WinForms)使用的約定與System.Windows.Media(WPF)使用的約定之間存在許多不兼容性。 。 例如,他們使用不同的度量單位(像素與固定的96dpi),不同的坐標類型(int vs double),不同的線條繪制規則,不同的旋轉,不同的brushm,立即vs保留模式等。

WPF的System.Windows.Media庫比WinForms的System.Drawing (GDI +)庫強大得多。 WPF包含更多變換,更好的不透明度支持,3D和其他功能,允許使用System.Drawing (GDI +)非常困難的效果。

但是,問題中提出的代碼是否可以與WPF一起使用?

是的,它會的。 只要您在WPF上運行而不是像Silverlight這樣的克隆,您仍然可以訪問舊的WinForms庫。 因此,您可以繼續使用System.Drawing調用來繪制您的圖形。 但你無法獲取生成的Bitmap並將其簡單地插入到WPF應用程序中:位圖是不兼容的,並且像往常一樣WPF位圖更強大。 有一些方法可以將位圖轉換為WPF位圖,或者可以將其保存為標准文件格式(如.png)並重新加載。

由於問題中提出的代碼實際上確實將位圖保存為.png文件,因此實際上可以不加改變地使用它。 但是,如果在創建位圖時需要任何新的WPF功能,或者如果要在不保存到文件的情況下使用位圖,則需要特殊技術。

那你為什么不想按原樣使用這段代碼呢?

也許你會這樣:如果你正在做一個快速的應用程序並且已經編寫了代碼,並且你確實想要將文件存儲到磁盤,那么沒有理由將代碼轉換為WPF。 但是,如果您想使用新的WPF功能或使用數據綁定或其他動態技術將圖像直接合並到WPF用戶界面,您可能希望將程序轉換為使用WPF的庫而不是使用WinForms。 這是根據您的需求進行的判斷。

您的問題詢問了使用此代碼“使用WPF”所需的條件。 答案是:沒什么。 您的代碼編寫普通的.png文件,WPF讀取普通的.png文件。 所以它會奏效。

如果您的代碼是使用COBOL或Java或任何其他原始語言從90年代調用基於Unix的繪圖庫,則可以說同樣的事情。 只要代碼最終編寫標准.png文件(或.gif或.jpg或...),其輸出將與WPF一起使用。 正如有令人信服的理由不將代碼保留在COBOL或Java中一樣,有理由不使用System.Drawing保留代碼:

  1. 依賴於System.Drawing隨着時間的推移可能會或可能不會出現WPF可以使用。
  2. 你可以畫的限制
  3. 與其他WPF代碼不同的繪圖模型

那么我如何使用WPF來代替WinForms呢?

您可以使用三個簡單的步驟從WPF中顯示的任何內容中制作位圖:

  1. 使用XAML或代碼構建WPF Visual。
  2. 在代碼中,構造一個所需大小的RenderTargetBitmap然后調用.Render(visual)
  3. 在應用程序的其他位置使用生成的位圖,或使用PngBitmapEncoder或類似方法保存它。

對於您的特定示例,我可能會使用如下的DataTemplate:

<DataTempate x:Key="NumberTemplate">
  <TextBlock
    Background="White"
    HorizontalAlignment="Center" VerticalAlignment="Center"
    FontFamily="Helvetica" FontSize="55"
    Text="{Binding}"
  />
</DataTemplate>

然后你寫出文件的實際代碼是:

void CreatePng(int number, string location, int width, int height)
{
  WritePng(location + "/" + number + "-" + width + "x" + height + ".png",
           new ContentPresenter  // Invokes a DataTemplate on its content
           {
             Content = number.ToString(),
             Template = NumberTemplate,
             Width = width, Height = height
           });
}

或者,您可以省略模板,只需在代碼中構造TextBlock來代替ContentPresenter。 但是模板可以很容易地快速改變你的外觀並添加不透明度,漸變畫筆,位圖效果等花哨的東西,所以我建議使用模板,除非你絕對確定你的外觀永遠不會改變。

WritePng()方法是一個通用的單幀.png文件編寫器,它在一個簡單的界面中封裝了WPF的高級功能。 它的編碼如下:

void WritePng(string path, UIElement element)
{
  // Create the bitmep specifying the size, pixel format and DPI
  var bitmap = new RenderTargetBitmap((int)element.Width, (int)element.Height,
                                      96, 96, PixelFormats.Pbgra32);
  bitmap.Render(element); // At this point the bitmap is usable within WPF

  // Write to a file:  WPF can write multiple frames but we need only one
  var encoder = new PngBitmapEncoder();
  encoder.Frames.Add(BitmapFrame.Create(bitmap));
  using(Stream stream = File.Create(path))
    encoder.Save(stream);  // Could be any stream, not just a file
}

我認為,這在WPF中會運行得很好。 它使用的是System.Drawing ,而不是System.Windows.Forms

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM