2013-06-11 208 views
0

下面是完整的程序(XAML和後面的代碼)。在啓動時,你會看到: enter image description here如何獲取Canvas.SetTop以處理ItemsCollection項目?

當你點擊[顯示/隱藏]你看: enter image description here

當您取消家庭和文件,然後單擊[應用]你看: enter image description here

由於您可以看到,「主頁」和「文檔」文件夾消失,但其他文件夾不會向上移動。查看兩個列表框,您會看到每行三個項目,文件夾標籤,Canvas.SetTop的值以及True:Visibility.Visible或False:Visibility.Collapsed。原始展示位置列表框是原始值。每次點擊[應用]時,新安置列表框會顯示新值。 Visibility值被應用並且結果是可見的,或者文件夾在那裏或不是。但是,應用Canvas.SetTop不起作用。你可以看到Canvas.SetTop的值已經改變。而且,如果你看一下代碼,你會看到,由於能見度應用到它應用到相同的UIElement:

    var f = Me[i]; 
        Canvas.SetTop(iec, f.Top);   // Why does this not work and 
        iec.Visibility = f.FolderVisible; // this does work? 

我需要的是可見的文件夾上移採取這些的地方,崩潰了。 Canvas.SetTop不起作用。我怎樣才能讓文件夾移動?

這裏是Solution Explorer窗格中,讓你知道什麼是需要: enter image description here

這裏是XAML:

<Window x:Class="FolderTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:system="clr-namespace:System;assembly=mscorlib" 
     xmlns:local="clr-namespace:FolderTest" 
     Title="Folder Test" 
     Width="450" 
     Height="410"> 
    <Grid Margin="10"> 
     <StackPanel Orientation="Horizontal"> 
      <StackPanel Orientation="Vertical"> 
       <!-- Folder Show/Hide Button --> 
       <Button Name="FolderOptions" Content="Show/Hide" FontSize="8" FontWeight="Bold" Width="50" Height="20" Margin="116, 0, 0, 0" Click="Event_ShowHide_ButtonClick" /> 
       <!-- Folders --> 
       <Grid> 
        <Canvas Name="xFolders" 
          Width="170" 
          Height="309" 
          VerticalAlignment="Top" 
          HorizontalAlignment="Left" 
          Margin="0,10,0,0"> 
         <Canvas.Resources> 
          <local:Folders x:Key="myFolders" /> 
         </Canvas.Resources> 
         <ItemsControl ItemsSource="{Binding Source={StaticResource myFolders}}"> 
          <ItemsControl.Template> 
           <ControlTemplate> 
            <ItemsPresenter /> 
           </ControlTemplate> 
          </ItemsControl.Template> 
          <ItemsControl.ItemsPanel> 
           <ItemsPanelTemplate> 
            <Canvas /> 
           </ItemsPanelTemplate> 
          </ItemsControl.ItemsPanel> 
          <ItemsControl.ItemTemplate> 
           <DataTemplate> 
            <DataTemplate.Resources> 
            </DataTemplate.Resources> 
            <Canvas Name="FolderCanvas" 
              Tag="{Binding Path=Number}" 
              Visibility="{Binding Path=FolderVisible}"> 
             <Path Data="{Binding Path=FolderPath}" 
               Stroke="{Binding Path=Brush}" 
               Fill="{Binding Path=Brush}"/> 
             <StackPanel Orientation="Horizontal" 
                Canvas.Left="5" 
                Canvas.Top="2"> 
              <TextBlock Text="{Binding Path=Label}" 
                 FontSize="12" 
                 Margin="20, 0, 0, 0" /> 
             </StackPanel> 
            </Canvas> 
           </DataTemplate> 
          </ItemsControl.ItemTemplate> 
          <ItemsControl.ItemContainerStyle> 
           <Style> 
            <Setter Property="Canvas.Top" 
              Value="{Binding Top}" /> 
           </Style> 
          </ItemsControl.ItemContainerStyle> 
         </ItemsControl> 
        </Canvas> 
       </Grid> 
      </StackPanel> 
      <StackPanel Orientation="Vertical" Margin="10, 0, 0, 0"> 
       <TextBlock Text="Original Placemet:" /> 
       <ListBox Name="OriginalPlacement" /> 
       <Button Name="Refresh" Content="New Placemet:" Margin="0, 10, 0, 0" Click="Event_OriginalPlacement_ButtonClick" /> 
       <ListBox Name="NewPlacement" /> 
      </StackPanel> 
     </StackPanel> 
    </Grid> 
</Window> 

下面是C#代碼背後:

using System; 
using System.Collections.Generic; 
using System.Windows.Media; 
using System.Windows.Controls; 
using System.Windows; 
using System.Collections.ObjectModel; 
using System.Windows.Controls.Primitives; 
using System.Windows.Input; 

namespace FolderTest 
{ 
    public struct GD 
    { 
     public static MainWindow MainWindow = null; 
     public static Button Refresh = null; 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      GD.MainWindow = this; 
      InitializeComponent(); 
      Loaded += new RoutedEventHandler(MainWindow_Loaded); 
     } 

     void MainWindow_Loaded(object sender, RoutedEventArgs e) 
     { 
      GD.Refresh = Refresh; 
      Folders.Placement(ref OriginalPlacement); 
     } 

     private void Event_ShowHide_ButtonClick(object sender, RoutedEventArgs e) 
     { 
      var pu = Folders.FolderShowPopUp(); 
      pu.PlacementTarget = FolderOptions; 
      pu.IsOpen = true; 
     } 

     private void Event_OriginalPlacement_ButtonClick(object sender, RoutedEventArgs e) 
     { 
      Folders.Placement(ref NewPlacement); 
     } 
    } 

    public class Folder 
    {// Specification for each folder tab seen on the left. 
     public int Number { get; set; }       // Folder sequence number top to bottom starging with 1. 
     public string Label { get; set; }      // The label that appears on the folder tab itself. 
     public double Top { get; set; }       // Position of the upper left corner of this folder. 
     public SolidColorBrush Brush { get; set; }    // Solid Color Brush. 
     public string FolderPath { get; set; }     // Contains the geometric path to draw this folder and its tab. 
     public Visibility FolderVisible { get; set; }   // This folder's Show/Hide flag. 

     public Folder(int Number, string Label, double Top, SolidColorBrush Brush, string FolderPath, Visibility FolderVisible) 
     { 
      this.Number = Number; 
      this.Label = Label; 
      this.Top = Top; 
      this.Brush = Brush; 
      this.FolderPath = FolderPath; 
      this.FolderVisible = FolderVisible; 
     } 
    } 

    public class Folders : ObservableCollection<Folder> 
    { 

     public static ObservableCollection<Folder> Me = null; 

     private static string[] Labels = new string[] 
     { 
      "Personal", 
      "Health", 
      "Finances", 
      "Home", 
      "Employment", 
      "Insurance", 
      "Documents", 
      "Contacts", 
      "Journal" 
     }; 

     private static Dictionary<string, Tuple<bool, bool>> LabelData = new Dictionary<string, Tuple<bool, bool>>() 
     {// Label       Show Hidable 
      {Labels[0], new Tuple<bool, bool>(true, false)}, 
      {Labels[1], new Tuple<bool, bool>(true, true)}, 
      {Labels[2], new Tuple<bool, bool>(true, true)}, 
      {Labels[3], new Tuple<bool, bool>(true, true)}, 
      {Labels[4], new Tuple<bool, bool>(true, true)}, 
      {Labels[5], new Tuple<bool, bool>(true, true)}, 
      {Labels[6], new Tuple<bool, bool>(true, true)}, 
      {Labels[7], new Tuple<bool, bool>(true, false)}, 
      {Labels[8], new Tuple<bool, bool>(true, true)} 
     }; 

     private static string[] FolderColors = new string[] 
     { 
      "FF36579E", 
      "FFDF2024", 
      "FF16A146", 
      "FF00B2D4", 
      "FFF47B20", 
      "FF9F1F63", 
      "FF13A89E", 
      "FFB7B7E7", 
      "FF50CAF5", 
      "FFAA9E74", 
      "FF86787D", 
      "FF36D146", 
     }; 

     private static byte[] ARGBColor = new byte[4];   // Byte array for the folder top color. 
     private static void ColorString2ARGB(ref byte[] bytes, string Hex) 
     {// Converts 8 char hex string to 4 byte array. 
      for (int i = 0; i < 8; i += 2) 
       bytes[i/2] = Convert.ToByte(Hex.Substring(i, 2), 16); 
     } 

     private static int colorIndex = -1; // Initial value of the colorIndex. 
     private static string NextColor() 
     {// Returns a 8 char string containing the next top FolderColor. If at end, cycle to beginning. 
      colorIndex++; 
      if (colorIndex >= FolderColors.Length) colorIndex = 0; 
      return FolderColors[colorIndex]; 
     } 

     private class FolderShow 
     { 
      public string Label { get; set; } 
      public bool Show { get; set; } 
      public bool Hidable { get; set; } 
      public FolderShow(string label, bool show, bool hidable) 
      { 
       Label = label; 
       Show = show; 
       Hidable = hidable; 
      } 
     } 
     private static List<FolderShow> FolderShowList = null; 

     public static Popup FolderShowPopUp() 
     { 
      var pu = new Popup() 
      { 
       Placement = PlacementMode.Right, 
       AllowsTransparency = true, 
       StaysOpen = false 
      }; 
      var b = new Border() 
      { 
       BorderThickness = new Thickness(2), 
       BorderBrush = new SolidColorBrush() { Color = Colors.Black }, 
       CornerRadius = new CornerRadius(5), 
       Background = new SolidColorBrush() { Color = Colors.White } 
      }; 
      var sp = new StackPanel() 
      { 
       Orientation = Orientation.Vertical, 
       Margin = new Thickness(10) 
      }; 
      var tb = new TextBlock() 
      { 
       Text = "Checked Folders will be Displayed: ", 
       FontSize = 16, 
       FontWeight = FontWeights.Bold, 
      }; 

      sp.Children.Add(tb); 

      foreach (var fs in FolderShowList) 
      { 
       var cb = new CheckBox() 
       { 
        Content = fs.Label, 
        IsChecked = fs.Show, 
        IsEnabled = fs.Hidable, 
        FontSize = 14, 
        FontWeight = FontWeights.Bold, 
        Margin = new Thickness(0, 5, 0, 0) 
       }; 
       cb.Click += new RoutedEventHandler(Event_CheckBoxFolderList_Click); 
       sp.Children.Add(cb); 
      } 

      var bp = new StackPanel() 
      { 
       Orientation = Orientation.Horizontal, 
       Margin = new Thickness(0, 5, 0, 0) 
      }; 
      var ba = new Button() { Content = "Apply", Width = 50, Height = 25, BorderBrush = new SolidColorBrush(Colors.Transparent), Tag = pu }; 
      ba.Click += new RoutedEventHandler(Event_ApplyFolderList_Click); 
      bp.Children.Add(ba); 
      var bc = new Button() { Content = "Cancel", Width = 50, Height = 25, BorderBrush = new SolidColorBrush(Colors.Transparent), Tag = pu, Margin = new Thickness(7, 0, 0, 0) }; 
      bc.Click += new RoutedEventHandler(Event_CancelFolderList_Click); 
      bp.Children.Add(bc); 
      sp.Children.Add(bp); 

      var tbm = new TextBlock() 
      { 
       Text = "Disabled folders cannot be hidden.", 
       Margin = new Thickness(0, 5, 0, 0), 
       FontSize = 12, 
       Foreground = new SolidColorBrush() { Color = Colors.Red } 
      }; 
      sp.Children.Add(tbm); 

      b.Child = sp; 
      pu.Child = b; 

      return pu; 
     } 

     private static void Event_CheckBoxFolderList_Click(object sender, RoutedEventArgs e) 
     { 
      var cb = (CheckBox)e.Source; 
      foreach (var fs in FolderShowList) 
      { 
       if (fs.Label == cb.Content as string) 
       { 
        fs.Show = (bool)cb.IsChecked; 
        break; 
       } 
      } 
     } 

     private static void Event_CancelFolderList_Click(object sender, RoutedEventArgs e) 
     { 
      ((Popup)((Button)e.Source).Tag).IsOpen = false; 
     } 

     private static void Event_ApplyFolderList_Click(object sender, RoutedEventArgs e) 
     { 
      foreach (var fs in FolderShowList) 
      { 
       var sh = LabelData[fs.Label]; 
       LabelData[fs.Label] = new Tuple<bool, bool>(fs.Show, sh.Item2); 
      } 
      ((Popup)((Button)e.Source).Tag).IsOpen = false; 

      int p = 0; 
      foreach (var f in Me) 
      { 
       var fs = LabelData[f.Label].Item1 == true; 
       f.Top = p * folderPositionFactor; 
       f.FolderVisible = fs ? Visibility.Visible : Visibility.Collapsed; 
       if (fs) p += 1; 
      } 
      foreach (ItemsControl ic in GD.MainWindow.xFolders.Children) 
      { 
       for (int i = 0; i < ic.Items.Count; i++) 
       { 
        var ie = (UIElement)ic.ItemContainerGenerator.ContainerFromIndex(i); 
        var iec = Controls.FindChildByType<Canvas>(ie, "FolderCanvas"); 
        if (iec != null) 
        { 
         var f = Me[i]; 
         Canvas.SetTop(iec, f.Top);   // Why does this not work and 
         iec.Visibility = f.FolderVisible; // this does work? 
        } 
       } 
       break; 
      } 
      GD.Refresh.RaiseEvent(new RoutedEventArgs(Button.ClickEvent)); 
     } 

     public static void Placement(ref ListBox lb) 
     { 
      lb.Items.Clear(); 
      foreach (ItemsControl ic in GD.MainWindow.xFolders.Children) 
      { 
       for (int i = 0; i < ic.Items.Count; i++) 
       { 
        var ie = (UIElement)ic.ItemContainerGenerator.ContainerFromIndex(i); 
        var iec = Controls.FindChildByType<Canvas>(ie, "FolderCanvas"); 
        if (iec != null) 
        { 
         var f = Me[i]; 
         lb.Items.Add(f.Label + ": " + f.Top.ToString() + ", " + (f.FolderVisible == Visibility.Visible ? "True" : "False")); 
        } 
       } 
       break; 
      } 
     } 


     public Folders() 
     {// The constructor, initializes itself by creating a folder for each label in Labels 
      FolderShowList = new List<FolderShow>(); 
      for (int i = 0; i < Labels.Length; i++) 
      { 
       string n = Labels[i]; 
       bool h = LabelData[Labels[i]].Item2; 
       bool s = h == true ? LabelData[Labels[1]].Item1 == true : true; 
       FolderShowList.Add(new FolderShow(n, s, h)); 
      } 
      SetFolders(); 
      Me = this; 
     } 

     const double folderPositionFactor = 31; // 21.80; 
     public void SetFolders() 
     { 
      SolidColorBrush[] scb = new SolidColorBrush[Labels.Length];   // Hold the linear solid color brush to assign to the folder. 
      Color[] pointerColor = new Color[Labels.Length];      // Hold the color to assign to the folder's solid color brush. 

      for (int i = 0; i < Labels.Length; i++) 
      {// Create a solid color brush for each folder. 
       ColorString2ARGB(ref ARGBColor, NextColor());            // Color into byte array. 
       Color TmpColor = Color.FromArgb(ARGBColor[0], ARGBColor[1], ARGBColor[2], ARGBColor[3]); // Create top color. 
       pointerColor[i] = TmpColor; 
       SolidColorBrush TmpSCB = new SolidColorBrush() { Color = TmpColor }; 
       scb[i] = TmpSCB; // Assign the solid color brush. 
      } 

      // All is ready to create the individual folders. 
      const string folderHeight = "56"; // "44"; 
      Brush FontColor = Brushes.Black;           // Initial font color for labels. 
      string fp = "M0,7 A7,7 90 0 1 7,0 L100,0 105,18 150,18 150,FH 0,FH Z".Replace("FH", folderHeight); // Initial geometric path for folder design. 
      int afp = 0; // Actual Folder Position. 
      for (int i = 0; i < Labels.Length; i++) 
      {// Create the individual folders. 
       bool fs = FolderShowList[i].Show; 
       Add(new Folder(
           i + 1,           // Folder sequence count. 
           Labels[i],          // Folder label. 
           afp * folderPositionFactor,      // Position of top of folder. 
           scb[i % scb.Length],       // Solid color brush. 
           fp,            // Geometric path for folder design. 
           fs ? Visibility.Visible : Visibility.Collapsed // User Hidden. 
          ) 
         ); 
       if (fs) afp += 1; 
       if (i == 0) 
       {// First folder created, now set values for remaining folders. 
        FontColor = Brushes.White; 
        fp = "M0,25 A7,7 90 0 1 7,18 L13,18 18,0 100,0 105,18 150,18 150,FH 0,FH Z".Replace("FH", folderHeight); 
       } 
      } 
     } 
    } 

    public static class Controls 
    { 

     public static T FindChildByType<T>(DependencyObject parent, string childName) where T : DependencyObject 
     { 
      if (parent == null) return null; // No parent, get out of here. 
      T foundChild = null; 
      int childrenCount = VisualTreeHelper.GetChildrenCount(parent); 
      for (int i = 0; i < childrenCount; i++) 
      { 
       var child = VisualTreeHelper.GetChild(parent, i); 
       // If the child is not of the request child type child 
       T childType = child as T; 
       if (childType == null) 
       { 
        // recursively drill down the tree 
        foundChild = FindChildByType<T>(child, childName); 

        // If the child is found, break so we do not overwrite the found child. 
        if (foundChild != null) break; 
       } 
       else if (!string.IsNullOrEmpty(childName)) 
       { 
        var frameworkElement = child as FrameworkElement; 
        // If the child's name is set for search 
        if (frameworkElement != null && frameworkElement.Name == childName) 
        { 
         // if the child's name is of the request name 
         foundChild = (T)child; 
         break; 
        } 
       } 
       else 
       { 
        // child element found. 
        foundChild = (T)child; 
        break; 
       } 
      } 
      return foundChild; 
     } 
    } 
} 

感謝您提供的任何幫助。

回答

0

我終於想出了答案,它非常簡單。

這是代碼將被改變(中心線只):

    var f = Me[i]; 
        Canvas.SetTop(iec, f.Top);   // Why does this not work 
        iec.Visibility = f.FolderVisible; // and this does work? 

這是新的代碼(僅中心線被改變時,實際上,只有一個字符被移除):

    var f = Me[i]; 
        Canvas.SetTop(ie, f.Top); 
        iec.Visibility = f.FolderVisible; 

也就是說,將Canvas.SetTop(iec, f.Top);更改爲Canvas.SetTop(ie, f.Top);即只將iec更改爲ie,並且所有工作正常。

+0

的'ItemsControl'包裝在'ContentPresenter'每個元素,你需要確保你設置'Canvas.Top'在'ContentPresenter',而不是在'ItemTemplate'內的項目。這就是'ItemContainerStyle'的作用 - 它在'ContentPresenter'上設置值 – Rachel

相關問題