现在的位置: 首页 > 综合 > 正文

WPF FAQ

2013年10月17日 ⁄ 综合 ⁄ 共 14094字 ⁄ 字号 评论关闭

I am excited to announce the availability of the following FAQ paper which lists some of the questions frequently asked by the WPF forum members. This paper has covered many parts of WPF from the application model to base services to graphics, animation etc. Although it’s far from complete, but this is the first attempt our forum support team has been trying to make to help development community members find the answers to their questions much easier and fast, and it’s always the top priority for our team to make the MSDN forum a good place for developers to ask questions, talk about technologies etc. With time goes on, this thread will be enhanced with more FAQs and content, so we really welcome and appreciate any feedback or suggestion on how to improve it.


On behalf of the whole forum support team, I want to thank
Ian Griffiths from the community for his uncompromising technical review on this paper. And I also want to thank Dwayne Need from the WPF team for his expert tips on how to explain the nitty-gritty aspects of WPF. His final technical review is gorgeous and definitive. And finally I want to thank all the WPF forum members who actively participate in this forum and help others.

 



1. Application Model

1.1 Is WPF resolution independent?
1.2 Should we manually cleanup the resources used by WPF bitmaps or Image controls?
1.3 Is it possible to change the Z-order of hosted Windows Forms control in WPF?
1.4 How to host a WPF/XBAP application in ASP.NET pages?
1.5 How to use Windows Forms control (e.g. Crystal Report Viewer) in a WPF application?
1.6 Is it possible to subclass from XAML generated class in WPF?

2. Base Services (Threading, Keyboard/Mouse handling & Dependency Properties)

2.1 Where is Application.DoEvents in WPF?
2.2 How to access WPF controls from another thread?

 

3. Controls

3.1 How to expand all nodes (TreeViewItems) of TreeView control?
3.2 How to do lasso (drag & select) selection in ListBox/ListView?
3.3 How to implement RadioButtonList type of control in WPF?
3.4 How to keep only one Expander control opened in a group of Expander controls?
3.5 How to automatically check TreeView children nodes when parent is checked?
3.6 What is ContentPresenter?

4. Text & Documents

4.1 How to find and replace text in RichTextBox?

5. Styles

5.1 When styling Button control, why does it have different theming behaviors under Windows XP and Windows Vista?
5.2 How to re-style or re-template a Popup control?
5.3 How to customize a Window in WPF?

6. Data Service

6.1 What's the difference between TemplateBinding and Binding?
6.2 What is CollectionView?
6.3 How to enable multi-threaded data binding in WPF?

7. Visuals (2D/3D Graphics, Animation & Media)

7.1 How to use RenderTargetBitmap?
7.2 How to animate the size of a Window in WPF?
7.3 Why Viewport2DVisual3D.Camera is frozen when animating it?

 

8. Imaging

8.1 Is there any efficient method in WPF to draw graphics at pixel level?

 

 

 

 

 

Edited by Marco Zhou on 2008年6月26日 11:29:49
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 11:34:08
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 11:38:46
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 11:50:09
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 11:52:29
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 16:30:07
Note: add preface
Edited by Marco Zhou on 2008年6月26日 16:34:21
Note: correct stuff
Edited by Marco Zhou on 2008年6月26日 17:01:40
Note: correct font
  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 11:18:15
      

    1.  Application Model

    1.1 Is WPF resolution independent?

     

    This is an occasionally confusing aspect of WPF. Thank Charles Petzold for his concise and definitive answer:

     

    The Windows user is ultimately responsible for setting an assumed resolution of the video display. This is done in the Display Properties applet. Commonly this assumed resolution is 96 or 120 DPI but it could be set higher. This has been the case for several past versions of Windows and it remains unchanged in Vista.

    The assumed resolution is independent of the actual resolution of the monitor. The user can try to set the assumed resolution equal to the actual resolution, but there is little reason for it. But again, nothing has changed with Vista.

    WPF programming involves device-independent units of 1/96th inch. If the assumed resolution of the video display is 96 DPI, then WPF DIUs correspond directly with pixels. If the assumed resolution of the video display is 120 DPI, then WPF DIUs are equal to 1-1/3 pixels.

    Functionally, there is no real change. For decades, Windows programmers have either been obtaining the assumed resolution of the video display or using mapping modes based on this assumed resolution. The whole process is somewhat more convenient in WPF than in previous Windows APIs, but it's functionally the same.

    The WPF DIU is only something the programmer sees. It does not affect users at all. Users are not required to make any adjustments to accommodate the WPF DIU.

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3057227&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2566603&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1857144&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2804844&SiteID=1

    Edited by Marco Zhou on 2008年6月26日 11:47:06
    Note: correct stuff
  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 12:03:04

    1.2 Should we manually cleanup the resources used by WPF bitmaps or Image controls?

    Unlike Windows Forms, WPF has implemented a unified model for managing resources such as brushes, textures/bitmaps, video/audio etc. Let's take Image control for example, if the Image control is disconnected from the visual tree, its underlying unmanaged resources such as bitmaps will be released by the underlying MIL (Media Integration Layer), and if there are no outstanding managed references to it, the managed resources associated with it will be eligible for garbage collection. But if the unmanaged resources are explicitly created by your code, you are responsible for disposing them by implementing the dispose pattern.

    If you do find a memory leak problem or you suspect some of the objects are leaking in your application, you could use windbg or CLR profiler to track down those types of problems.

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3086068&SiteID=1

    1.3 Is it possible to change the Z-order of hosted Windows Forms control in WPF?

    Windows Forms control when hosted inside a WPF window will always be on top of other WPF visuals rendered into its containing Window. This is one of the limitations you should take into consideration when using HwndHost/WindowsFormsHost to host Win32/Windows Forms control.

    For more background information on this, you can refer the following MSDN article:
    http://msdn2.microsoft.com/en-us/library/aa970688.aspx

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3087729&SiteID=1

    Edited by Marco Zhou on 2008年6月26日 13:30:52
    Note: correct stuff
    Edited by Marco Zhou on 2008年6月26日 13:42:28
    Note: correct stuff
  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 12:28:24
    1.4 How to host a WPF/XBAP application in ASP.NET pages?

    Currently integration and interoperation between XBAP and ASP.NET is quite limited. Fortunately you can use HTML iframe element to host XBAP application, and use either cookies or query strings to communicate between ASP.NET and XBAP. Furthermore, if you really need a richer integration or interoperation features, you could try Silverlight (a subset of WPF) which is designed and optimized for web scenario.

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2870386&SiteID=1

    1.5 How to use Windows Forms control (e.g. Crystal Report Viewer) in a WPF application?

     

    <Window
       x:Class="ForumProjects.MainWindow"
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
       xmlns:c="clr-namespace:CrystalDecisions.Windows.Forms;assembly=CrystalDecisions.Windows.Forms"
       Title="MainWindow" Width="800" Height="600">
      <
    WindowsFormsHost>
        <
    c:CrystalReportViewer x:Name="MyCrystalReportViewer" Width="300" Height="300"/>
      </
    WindowsFormsHost>
    </
    Window>

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2909472&SiteID=1

    1.6 Is it possible to subclass from XAML generated class in WPF?

     

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2829770&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2710858&SiteID=1

    The current version of WPF doesn't support subclassing from XAML generated class if the subclass also uses XAML. In order to let the base class inheritable by XAML generated subclass, you need to write the base class completely in code.

    We can use WindowsFormsHost element to host a Windows Forms control in WPF. Here is an example which shows how to host a CrystalReportViewer

    Edited by Marco Zhou on 2008年6月26日 15:07:52
    Note: correct stuff
  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 12:55:53

    2. Base Services (Threading, Keyboard/Mouse handling & Dependency Properties)

    2.1 Where is Application.DoEvents in WPF?

    Unlike Windows Forms, WPF doesn't directly provide an Application.DoEvents() equivalent to allow developers to start nesting message pumping. When writing Windows application, you'd better try to avoid using nested message pumping, because nested message pumping could cause some subtle problems such as code reentrancy, and what's more, WPF will disable nested message pumping when doing layout, visual tree traversal among other things.

    But there would be some rare situations in which nested message pumping could be useful, such as unit testing, the following helper class could provide the Application.DoEvents like feature in WPF:

    /// <summary>
    ///
    Encapsulates a WPF dispatcher with added functionalities.
    /// </summary>
    public class DispatcherHelper
    {
        private static DispatcherOperationCallback exitFrameCallback = new
             DispatcherOperationCallback(ExitFrame);

        /// <summary>
        /// Processes all UI messages currently in the message queue.
        /// </summary>
        public static void DoEvents()
        {
            // Create new nested message pump.
            DispatcherFrame nestedFrame = new DispatcherFrame();

            // Dispatch a callback to the current message queue, when getting called,
            // this callback will end the nested message loop.
            // note that the priority of this callback should be lower than that of UI event messages.
            DispatcherOperation exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(
                DispatcherPriority.Background, exitFrameCallback, nestedFrame);

            // pump the nested message loop, the nested message loop will immediately
            // process the messages left inside the message queue.
            Dispatcher.PushFrame(nestedFrame);

            // If the "exitFrame" callback is not finished, abort it.
            if (exitOperation.Status != DispatcherOperationStatus.Completed)
            {
                exitOperation.Abort();
            }
        }

        private static Object ExitFrame(Object state)
        {
            DispatcherFrame frame = state as DispatcherFrame;

            // Exit the nested message loop.
            frame.Continue = false;
            return null;
        }
    }

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2034805&SiteID=1
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=602081&SiteID=1

    Edited by Marco Zhou on 2008年6月26日 13:01:01
    Note: correct stuff
    Edited by Marco Zhou on 2008年6月26日 14:19:30
    Note: correct stuff
    Edited by Marco Zhou on 2008年6月26日 14:22:22
    Note: correct stuff
  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 13:21:27

    2.2 How to access WPF controls from another thread?

    Like many UI frameworks such as Windows Forms, WPF also imposes a single threading model, which means that you can only access a specified DispatcherObject derivative from the thread which creates it. In Windows Forms, each Control will implement ISynchronizeInvoke interface, this interface exposes a set of methods such as Invoke and BeginInvoke to impose a common thread synchronization contract which we could use to access a control from another thread. In WPF, we also have such type of thing, but those operations are wrapped up in a class called Dispatcher, Dispatcher is WPF way of enabling this type of thread synchronization model.

    The following is an example of how to modify the TextBox.Text property when the caller is in a different thread:

    // Resets textbox text from another thread
    textBox.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
    {
        textBox.Text = "New text";
    }));

    Related threads:
    http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3024118&SiteID=1

  • Marco ZhouMSFT, Moderator - Posted on 2008年6月26日 14:03:33

    3. Controls

    3.1 How to expand all nodes (TreeViewItems) of TreeView control?

    Unlike Windows Forms, the current version of WPF doesn't provide a straightforward way to expand all nodes of TreeView control with a single line of code. Generally speaking, there are two ways to implement this feature. The first method is to leverage WPF's Styling capability as the following XAMLPad ready example shows:

    <Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <
    Page.Resources>
        <
    XmlDataProvider x:Key="treeData" XPath="*">
          <
    x:XData>
            <
    Items Name="Items" xmlns="">
              <
    Item1/>
              <
    Item2>
                <
    Item22/>
                <
    Item12/>
                <
    Item13>
                  <
    Item131/>
                  <
    Item131/>
                </
    Item13>
              </
    Item2>
            </
    Items>
          </
    x:XData>
        </
    XmlDataProvider>

        <HierarchicalDataTemplate ItemsSource="{Binding XPath=child::*}"
                                 
    x:Key="template">
          <
    TextBlock Name="textBlock" Text="{Binding Name}"/>
        </
    HierarchicalDataTemplate>
      </
    Page.Resources>
      <
    TreeView ItemTemplate="{StaticResource template}"
               
    ItemsSource="{Binding Source={StaticResource treeData}}">
        <TreeView.ItemContainerStyle>
          <!--
    Using style setter to set the TreeViewItem.IsExpanded property to true, this will be applied
          to all TreeViweItems when they are generated
    -->
          <
    Style TargetType="{x:Type TreeViewItem}">
            <
    Setter Property="IsExpanded" Value="True"/>
          </
    Style>
        </
    TreeView.ItemContainerStyle>

      </

    TreeView>
    </
    Page>

    Sometimes, you need a programmatic way of doing this, and then you could use the following C# helper method to expand all nodes:

    public static class TreeViewHelper
    {
        public static void ExpandAll(TreeView treeView)
        {
            ExpandSubContainers(treeView);
        }

        private static void ExpandSubContainers(ItemsControl parentContainer)
        {
            foreach (Object item in parentContainer.Items)
            {
                TreeViewItem currentContainer = parentContainer.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
                if (currentContainer != null && currentContainer.Items.Count > 0)
                {
                    // Expand the current item.
                    currentContainer.IsExpanded = true;
                    if (currentContainer.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
                    {
                        // If the sub containers of current item is not ready, we need to wait until
                        // they are generated.
                        currentContainer.ItemContainerGenerator.StatusChanged += delegate
                        {
                            ExpandSubContainers(currentContainer);
                        };
                    }
                    else
                    {
                        // If the sub containers of current item is ready, we can directly go to the next
                        // iteration to expand them.
                        ExpandSubContainers(currentContainer);
                    }
                }
            }
        }
    }

    The key to this technique shown above is to make sure that the container for the current TreeViewItem has been generated, so you can safely expand it to show all its sub items. That's why you need to make a recursive call when the status of current TreeViewItem's ItemContainerGenerator is GeneratorStatus.ContainersGenerated.

  • 抱歉!评论已关闭.