2011-10-10 11 views
6

मैं एक बिटमैप पर एक WPF विजुअल (UserControl) प्रस्तुत कर रहा हूं लेकिन समस्या यह है कि प्रस्तुत की गई छवि उपयोगकर्ता नियंत्रण का आकार स्केल/ट्रांसफॉर्म होने से पहले है। तो मान लें कि UserControl 200x200 पिक्सल पर डिज़ाइन किया गया था। जब मैं बीएमपी को प्रस्तुत करता हूं तो मैं UserControl की ActualWidth और ActualHeightt का उपयोग कर रहा हूं जो क्रमश: 200 और 200 की रिपोर्ट करता है। समस्या यह है कि UserControl कैनवास में है और 1200 x 1200 (यह बदलता है)एक WPF दृश्य तत्व के स्केल किए गए आकार को कैसे प्राप्त करें

मैंने कुछ पढ़ने और खोज कर लिया है और अब तक ऑटो आकार (विंडो आकार के साथ स्केल/भरने के लिए सेट) है। प्रभावी आकार को निर्धारित करने के तरीके को समझें, यह आकार स्क्रीन पर नियंत्रण को आकार दिया जा रहा है।

मैं इस प्रश्न पर आया जो आशावादी लग रहा था लेकिन ट्रांसफॉर्म में वापस स्केलिंग डेटा नहीं था। वैसे यह करता है, लेकिन वे दोनों हैं 1. Get element position after transform

रेंडर स्केलिंग के लिए कहां देखना है, इस पर कोई सुझाव बहुत अच्छा होगा!

[अद्यतन] के रूप में सुझाव दिया, मैं प्रासंगिक कोड शामिल कर रहा हूँ:

public static Bitmap PngBitmap(this Visual visual) 
{ 
    // Get height and width 
    int width = (int)(double)visual.GetValue(
     FrameworkElement.ActualWidthProperty); 
    int height = (int)(double)visual.GetValue(
     FrameworkElement.ActualHeightProperty); 

    // Render 
    RenderTargetBitmap rtb = 
     new RenderTargetBitmap(
      width, 
      height, 
      96, 
      96, 
      PixelFormats.Default); 
    rtb.Render(visual); 

    // Encode 
    PngBitmapEncoder encoder = new PngBitmapEncoder(); 
    encoder.Frames.Add(BitmapFrame.Create(rtb)); 
    System.IO.MemoryStream stream = new System.IO.MemoryStream(); 
    encoder.Save(stream); 

    // Create Bitmap 
    Bitmap bmp = new Bitmap(stream); 
    stream.Close(); 

    return bmp; 
} 

public static BitmapSource BitmapSource(this Visual visual) 
{ 
    Bitmap bmp = visual.PngBitmap(); 
    IntPtr hBitmap = bmp.GetHbitmap(); 
    BitmapSizeOptions sizeOptions = BitmapSizeOptions.FromEmptyOptions(); 
    return Imaging.CreateBitmapSourceFromHBitmap(
         hBitmap, 
         IntPtr.Zero, 
         Int32Rect.Empty, 
         sizeOptions); 
} 

[# अद्यतन 2] जोड़ा गया XAML - क्योंकि यह विशाल था ग्रिड तत्व हटा दिया और से किया गया था मेरी एक्सएएमएल के कैनवास को पढ़ना कीबोर्ड युक्त उपयोगकर्ता नियंत्रण नियंत्रण ग्रिड तत्व का हिस्सा नहीं था।

<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:local="clr-namespace:PMD.HECAT.DashboardModule" 
    xmlns:PMD_HECAT_DashboardModule_VirtualKeyboard="clr-namespace:PMD.HECAT.DashboardModule.VirtualKeyboard" 
    xmlns:System_Windows_Controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit" 
    xmlns:PMD_HECAT_DashboardModule_Input="clr-namespace:PMD.HECAT.DashboardModule.Input" 
    xmlns:control="clr-namespace:PMD.HECAT.DashboardModule.Controls"  
    x:Class="PMD.HECAT.DashboardModule.CandidateElectrodeView"    
    x:Name="UserControl" 
    mc:Ignorable="d" 
    d:DesignWidth="1024" d:DesignHeight="768" Width="640" Height="360"> 
    <UserControl.Resources> 
     <ResourceDictionary> 
      <ResourceDictionary.MergedDictionaries> 
       <ResourceDictionary Source="../Themes/DashboardStyles.xaml" /> 
       <ResourceDictionary Source="../Themes/ImageButtons.xaml" /> 
       <ResourceDictionary Source="CandidateViewResources.xaml" /> 
      </ResourceDictionary.MergedDictionaries> 
     </ResourceDictionary>   
    </UserControl.Resources> 
    <UserControl.Triggers> 
     <EventTrigger RoutedEvent="PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.KeyboardClose" SourceName="virtualKeyboardView"> 
      <BeginStoryboard Storyboard="{StaticResource OnKeyboardClose1}"/> 
     </EventTrigger> 
    </UserControl.Triggers> 
    <Canvas Width="100" HorizontalAlignment="Left"> 

     <PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView x:Name="virtualKeyboardView" Height="222" Width="550" RenderTransformOrigin="0.5,0.5" Opacity="0" Active="False"> 
      <PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.RenderTransform> 
       <TransformGroup> 
        <ScaleTransform/> 
        <SkewTransform/> 
        <RotateTransform/> 
        <TranslateTransform X="40" Y="400"/> 
       </TransformGroup> 
      </PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView.RenderTransform> 
     </PMD_HECAT_DashboardModule_VirtualKeyboard:VirtualKeyboardView> 
     <Rectangle Stroke="White" Opacity="0.7" Fill="White" Height="370" Width="654.851" Canvas.Left="687" Canvas.Top="0" /> 
    </Canvas> 
</UserControl> 
+0

नियंत्रण में किस तरह का परिवर्तन लागू किया जाता है? लेआउट ट्रांसफॉर्म या/और रेंडरट्रांसफॉर्म? "ऑटो आकार" से आपका क्या मतलब है? –

+0

@ एर्नो - ईमानदारी से मैं पूरी तरह से यकीन नहीं कर रहा हूँ। मैं नया हूं, मैं WPF से नया हूं और अभी तक लेआउट टूल को समझ नहीं पा रहा हूं। ऐसा प्रतीत होता है कि UserControl एक कैनवास के अंदर है जो चौड़ाई और ऊंचाई –

+0

में फैलाने के लिए कॉन्फ़िगर किया गया है, तो हमें कोड दिखाएं ताकि हम सहायता कर सकें। –

उत्तर

5

मैं पारित कर दिया बहुत समय पता के बाद से प्रश्न पूछा गया था लेकिन यह कुछ अधिक जानकारी :)

मैं इस कोड का उपयोग लागू बदलने रेंडर (रों साथ दृश्यों का आकार (पैमाने) को खोजने के लिए पोस्ट करने के लिए चोट नहीं करता है)।

GeneralTransform t = transformedVisual.TransformToVisual(parentVisual); 

Vector topLeft = (Vector) t.Transform(new Point(0,0)); 
Vector topRight = (Vector) t.Transform(new Point(originalWidthOfTransformedVisual, 0)); 

double renderedWidth = (topRight-topLeft).Length; 
double widthScale = renderedWidth/originalWidthOfTransformedVisual; 
+3

ध्यान दें कि अधिक आम तौर पर, कोई माता-पिता के सापेक्ष दृश्य की सीमाओं की गणना कर सकता है: 'Rect bounds = t । ट्रांसफॉर्मबाउंड (नया रेक्ट (नया आकार (रूपांतरित विज़ुअल.एक्टुअलविड्थ, ट्रांसफॉर्म किया गया विज़ुअल.एक्टुअल हाइट)); 'बेशक, इसके लिए काम करने के लिए,' विज़ुअल 'को' सरल 'विज़ुअल के बजाय' फ्रेमवर्क एलिमेंट 'होना चाहिए (उत्तरार्द्ध अपने आप में कोई आयामी जानकारी नहीं है)। –

0

आप कहते हैं कि आप दृश्य की चौड़ाई और ऊंचाई का उपयोग करते हैं। सबसे पहले, दो समस्याएं हैं। एक दृश्य, http://msdn.microsoft.com/en-us/library/system.windows.media.visual.aspx में ऊंचाई और चौड़ाई के लिए कोई गुण नहीं है।

अब, मान लें कि आपके पास एक फ्रेमवर्क एलिमेंट है, जिसमें ऊंचाई और चौड़ाई संपत्ति है, क्या आप ऊंचाई और चौड़ाई गुणों, या वास्तविक हाइट और वास्तविक वाइड गुणों का उपयोग कर रहे हैं? यदि आप नहीं हैं, तो वे वे गुण हैं जिन्हें आप ढूंढ रहे हैं।

यदि आप उनका उपयोग कर रहे हैं, या आप फ्रेमवर्क एलिमेंट का उपयोग नहीं कर रहे हैं, तो आपको कुछ कोड पोस्ट करना चाहिए।

+0

भ्रम के लिए खेद है। यह वास्तव में एक UserControl है और मैं ActualWidth और ActualHeight का उपयोग कर रहा हूं (मैंने इसे स्पष्ट करने के लिए अपना मूल संदेश अपडेट किया है) –

1

If there is a RenderTransform you will hardly be able to determine the size unless you you some serious calculations

अधिकांश अन्य मामलों में आप ActualHeight और ActualWidth गुण का उपयोग करके FrameworkElement का आकार प्राप्त करने में सक्षम हो जाएगा। फिर भी, ये गुण आपको बाउंडिंग बॉक्स का आकार देंगे जो आपके द्वारा वर्णित परिदृश्य के लिए पर्याप्त होगा।

0

यदि आप Transform करने के लिए एनीमेशन का उपयोग कर सकते हैं तो एनीमेशन Completed ईवेंट प्रदान करता है। यह नया रूपांतरित आकार निकालने के लिए एक अच्छी जगह होनी चाहिए।

0
public static Rect GetRelativePlacement(this UIElement element, UIElement relativeTo) 
    { 
     var absolutePos = element.PointToScreen(new Point(0, 0)); 
     var posRelativeTo = relativeTo.PointToScreen(new Point(0, 0)); 

     var topLeft = new Point(absolutePos.X - posRelativeTo.X, absolutePos.Y - posRelativeTo.Y); 
     var bottomRight = element.PointToScreen(new Point(element.RenderSize.Width, element.RenderSize.Height)); 

     var bounds = Rect.Empty; 
     bounds.Union(topLeft); 
     bounds.Union(bottomRight); 

     return bounds; 
    } 
1

हाय मैं एक ऐसी ही समस्या थी, तो पहले इस प्रतिपादन

 uiElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); 
     uiElement.Arrange(new Rect(new Point(0, 0), uiElement.DesiredSize)); 
     Size _size = uiElement.DesiredSize; 

इस काम करता है कम से कम मेरे मामले में UIElement सामने यह प्रस्तुत करने के लिए मजबूर करने के लिए आकार दृश्य प्रदर्शित नहीं किया गया था

संबंधित मुद्दे