Clingingboy

<clingingboy:control runat="server"  />
Get Ready For WPF && SilverLight

博客园 首页 新随笔 联系 订阅 管理
  168 Posts :: 0 Stories :: 1258 Comments :: 280 Trackbacks

     这个帖子在微软官方的wpf讨论区http://forums.msdn.microsoft.com/en-US/wpf/thread/a2988ae8-e7b8-4a62-a34f-b851aaf13886
索性这个帖子是以前在我们博客园的同志sheva发的,不知道为何他建了一个新的bloghttp://shevaspace.blogspot.com/,不知道因为这篇blog的原因http://www.cnblogs.com/sheva/archive/2006/10/03/520583.html。。。。。So,有时间翻译翻译

3. 控件

3.1 如何展开TreeView 的所有节点(TreeViewItems) ?

不像Windows Forms,当前版本的WPF并没有提供以一行代码这样简单的方法来展开TreeView控件的所有节点。

一般而言,有两种方法可以实现这个功能.第一个方法是改变WPF 样式外观。以下xaml展示了这一方法:

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

有些时候,你需要以编程的方式来实现这一功能,你可以用下面c#的辅助方法来展开所有节点

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.

相关帖子:
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2014662&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=3180239&SiteID=1
http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1130017&SiteID=1

3.2 如何在ListBox/ListView中实现拖拽?

Lasso selection is used quite often in most graphical editing programs, and it's a convenient way to select multiple on-screen objects. The following shows how to enable this type of selection to the WPF ListBox/ListView controls:

<ListBox Name="listBox"
Width="200"
Height="200"
SelectionMode="Multiple">
  <ListBox.Resources>
    <Style TargetType="{x:Type ListBoxItem}">
      <EventSetter Event="ListBoxItem.PreviewMouseLeftButtonDown"
Handler="ListBoxItem_PreviewMouseLeftButtonDown"/>
      <EventSetter Event="ListBoxItem.PreviewMouseUp"
Handler="ListBoxItem_PreviewMouseUp"/>
      <EventSetter Event="ListBoxItem.PreviewMouseMove"
Handler="ListBoxItem_PreviewMouseMove"/>
    </Style>
  </ListBox.Resources>
  <x:Type TypeName="DependencyObject"/>
  <x:Type TypeName="Visual"/>
  <x:Type TypeName="UIElement"/>
  <x:Type TypeName="FrameworkElement"/>
  <x:Type TypeName="Control"/>
</ListBox> 

 

public partial class Window1 : Window
{
// This field is used to tell if ListBox is in mouse selection mode.
private Boolean inMouseSelectionMode = false;
// This field is used to keep track of the current mouse selected items.
private List<ListBoxItem> selectedItems = new List<ListBoxItem>();
public Window1()
    {
        InitializeComponent();
    }
private void ListBoxItem_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
// If the mouse is up, turn off "inMouseSelectionMode"
        inMouseSelectionMode = false;
    }
private void ListBoxItem_PreviewMouseMove(object sender, MouseEventArgs e)
    {
ListBoxItem mouseOverItem = sender as ListBoxItem;
if (mouseOverItem != null && inMouseSelectionMode && e.LeftButton == MouseButtonState.Pressed)
        {
            mouseOverItem.Background = SystemColors.HighlightBrush;
// Highlight the currently mouse-overed item.
            mouseOverItem.SetValue(TextElement.ForegroundProperty, SystemColors.HighlightTextBrush);
if (!selectedItems.Contains(mouseOverItem))
            {
                selectedItems.Add(mouseOverItem);
            }
        }
    }
private void ListBoxItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
// When the mouse is down, we need to clear all previously mouse selected items.
        listBox.SelectedIndex = -1;
        inMouseSelectionMode = true;
foreach (ListBoxItem item in selectedItems)
        {
            item.ClearValue(ListBoxItem.BackgroundProperty);
            item.ClearValue(TextElement.ForegroundProperty);
        }
        selectedItems.Clear();
    }
} 

 

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

3.3 How to implement RadioButtonList type of control in WPF?

WPF doesn't provide RadioButtonList control like ASP.NET does. Fortunately with WPF's powerful styling and templating capability, we could implement this type of control purely in XAML. Here is a XAMLPad ready example:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib">
  <Page.Resources>
    <x:Array Type="{x:Type s:String}" x:Key="data">
      <s:String>Option1</s:String>
      <s:String>Option2</s:String>
      <s:String>Option3</s:String>
    </x:Array>
  </Page.Resources>
  <StackPanel DataContext="{StaticResource data}">
    <TextBlock Margin="5">
      <TextBlock Text="Current Option:"/>
      <TextBlock Text="{Binding /}"/>
    </TextBlock>
    <ListBox
ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="True"
Width="240"
Height="60"
HorizontalAlignment="Left">
      <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="{x:Type ListBoxItem}">
                <RadioButton
IsChecked="{Binding Path=IsSelected, RelativeSource={RelativeSource TemplatedParent}}"
Content="{TemplateBinding Content}"/>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </ListBox.ItemContainerStyle>
    </ListBox>
  </StackPanel>
</Page> 

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

posted on 2008-07-06 18:26 Clingingboy 阅读(302) 评论(0)  编辑 收藏 所属分类: G.WPF

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2008-07-06 19:08 编辑过


相关链接: