/// <summary> /// Converts source values to a value for the binding target. The data binding engine calls this method when it propagates the values from source bindings to the binding target. /// </summary> /// <param name="values">The array of values that the source bindings in the <see cref="T:System.Windows.Data.MultiBinding"/> produces. The value <see cref="F:System.Windows.DependencyProperty.UnsetValue"/> indicates that the source binding has no value to provide for conversion.</param> /// <param name="targetType">The type of the binding target property.</param> /// <param name="parameter">The converter parameter to use.</param> /// <param name="culture">The culture to use in the converter.</param> /// <returns> /// A converted value.If the method returns null, the valid null value is used.A return value of <see cref="T:System.Windows.DependencyProperty"/>.<see cref="F:System.Windows.DependencyProperty.UnsetValue"/> indicates that the converter did not produce a value, and that the binding will use the <see cref="P:System.Windows.Data.BindingBase.FallbackValue"/> if it is available, or else will use the default value.A return value of <see cref="T:System.Windows.Data.Binding"/>.<see cref="F:System.Windows.Data.Binding.DoNothing"/> indicates that the binding does not transfer the value or use the <see cref="P:System.Windows.Data.BindingBase.FallbackValue"/> or the default value. /// </returns> public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { if (values.Length != 2) { return(null); } IDirectoryController directoryController = (IDirectoryController)values[0]; var history = directoryController.History; ObservableCollection <MenuItem> menuItems = new ObservableCollection <MenuItem>(); foreach (var item in history) { bool isDrive = (item.FileView.FullName.Length <= 3); string dir = item.FileView.FullName; bool isCurrent = item.IsCurrent; TextBlock header = new TextBlock { Text = isDrive ? DriveTypeHelper.GetDescription(new DriveInfo(dir)) : Path.GetFileName(dir), FontWeight = isCurrent ? FontWeights.Bold : FontWeights.Normal, }; MenuItem subDirMenuItem = new MenuItem { Header = header, Icon = new Image { Source = new FileView(dir).ImageSource } }; int historyOffset = item.HistoryOffset; subDirMenuItem.Click += delegate { directoryController.Navigate(historyOffset); }; menuItems.Add(subDirMenuItem); } return(menuItems); }
private void _viewModel_EnhancedPropertyChanged(object sender, EnhancedPropertyChangedEventArgs <IDirectoryController> e) { if (e.IsProperty(p => p.CurrentDirectory)) { string directory = _viewModel.CurrentDirectory; if (Directory.Exists(directory)) { ButtonGrid.Children.Clear(); ButtonGrid.ColumnDefinitions.Clear(); List <UIElement> buttons = new List <UIElement>(); string curdir = directory; while (Directory.Exists(curdir)) { if (curdir.EndsWith(@"\") && curdir.Length > 3) { curdir = curdir.Substring(0, curdir.Length - 1); } MenuItem menuItem; Menu menu; GetMenuItem(curdir, directory, out menuItem, out menu); if (menu != null) { buttons.Add(menu); } Button dirButton = new Button(); dirButton.Content = new TextBlock { Text = curdir.Length <= 3 ? DriveTypeHelper.GetDescription(new DriveInfo(curdir.Substring(0, 2))) : Path.GetFileName(curdir), Margin = new Thickness(2, 0, 2, 0) }; dirButton.VerticalAlignment = VerticalAlignment.Stretch; dirButton.VerticalContentAlignment = VerticalAlignment.Center; dirButton.Tag = curdir; dirButton.Click += (s, be) => { _viewModel.CurrentDirectory = (string)((Button)s).Tag; }; dirButton.Style = (Style)Application.Current.Resources["DirectoryButton"]; buttons.Add(dirButton); if (menuItem != null) { dirButton.MouseEnter += delegate { if (!menuItem.IsSubmenuOpen) { VisualStateManager.GoToState(menuItem, "MouseOver", true); } }; menuItem.MouseEnter += delegate { if (!menuItem.IsSubmenuOpen) { VisualStateManager.GoToState(dirButton, "MenuMouseOver", true); VisualStateManager.GoToState(menuItem, "MouseOver", true); } }; dirButton.MouseLeave += delegate { if (!menuItem.IsMouseOver && !menuItem.IsSubmenuOpen) { VisualStateManager.GoToState(menuItem, "Normal", true); } }; menuItem.MouseLeave += delegate { if (!dirButton.IsMouseOver && !menuItem.IsSubmenuOpen) { VisualStateManager.GoToState(dirButton, "Normal", true); VisualStateManager.GoToState(menuItem, "Normal", true); } }; menuItem.SubmenuOpened += delegate { VisualStateManager.GoToState(dirButton, "Pressed", true); VisualStateManager.GoToState(menuItem, "Pressed", true); }; menuItem.SubmenuClosed += delegate { if (!dirButton.IsMouseOver && !menuItem.IsMouseOver) { VisualStateManager.GoToState(dirButton, "Normal", true); VisualStateManager.GoToState(menuItem, "Normal", true); } else { VisualStateManager.GoToState(dirButton, "MouseOver", true); VisualStateManager.GoToState(menuItem, "MouseOver", true); } }; } curdir = Path.GetDirectoryName(curdir); } MenuItem rootMenuItem; Menu rootMenu; GetMenuItem(curdir, directory, out rootMenuItem, out rootMenu); rootMenuItem.MouseEnter += delegate { if (!rootMenuItem.IsSubmenuOpen) { VisualStateManager.GoToState(rootMenuItem, "MouseOver", true); } }; rootMenuItem.MouseLeave += delegate { if (!rootMenuItem.IsSubmenuOpen) { VisualStateManager.GoToState(rootMenuItem, "Normal", true); } }; rootMenuItem.SubmenuOpened += delegate { VisualStateManager.GoToState(rootMenuItem, "Pressed", true); }; rootMenuItem.SubmenuClosed += delegate { if (!rootMenuItem.IsMouseOver) { VisualStateManager.GoToState(rootMenuItem, "Normal", true); } else { VisualStateManager.GoToState(rootMenuItem, "MouseOver", true); } }; buttons.Add(rootMenu); FileView currentFileView = new FileView(directory); buttons.Add(new Image { Source = currentFileView.ImageSource, Margin = new Thickness(3, 3, 3, 3), VerticalAlignment = VerticalAlignment.Center }); for (int i = buttons.Count - 1, j = 0; i >= 0; i--, j++) { ButtonGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto }); buttons[i].SetValue(Grid.ColumnProperty, j); ButtonGrid.Children.Add(buttons[i]); } } } }
private void GetMenuItem(string curdir, string directory, out MenuItem menuItem, out Menu menu) { // TODO: Put "Path" as resource bool isDrive; string[] subdirs; if (curdir != null) { subdirs = Directory.GetDirectories(curdir); isDrive = false; } else { subdirs = DriveInfo.GetDrives().Select(p => p.Name).ToArray(); isDrive = true; } if (subdirs.Length == 0) { menuItem = null; menu = null; return; } menuItem = new MenuItem(); menuItem.VerticalAlignment = VerticalAlignment.Stretch; menuItem.VerticalContentAlignment = VerticalAlignment.Center; menuItem.Style = (Style)Application.Current.Resources["DirectoryMenuItemStyle"]; menuItem.Icon = new System.Windows.Shapes.Path { Data = (Geometry)Application.Current.Resources["RightArrow"], Height = 7, Width = 3.5, Fill = Brushes.Black, Margin = new Thickness(2, 0, 2, 0) }; foreach (string dir in subdirs) { if (!isDrive) { if (new DirectoryInfo(dir).Attributes.HasFlag(FileAttributes.Hidden)) { continue; } } bool isCurrent = (directory == dir || directory.StartsWith(dir + "\\")); TextBlock header = new TextBlock { Text = isDrive ? DriveTypeHelper.GetDescription(new DriveInfo(dir)) : Path.GetFileName(dir), FontWeight = isCurrent ? FontWeights.Bold : FontWeights.Normal }; MenuItem subDirMenuItem = new MenuItem { Header = header, Icon = new Image { Source = new FileView(dir).ImageSource }, Tag = dir }; subDirMenuItem.Click += delegate { ((IDirectoryController)DataContext).CurrentDirectory = (string)subDirMenuItem.Tag; }; menuItem.Items.Add(subDirMenuItem); } menu = new Menu(); menu.VerticalAlignment = VerticalAlignment.Stretch; menu.VerticalContentAlignment = VerticalAlignment.Center; menu.Style = (Style)Application.Current.Resources["MenuStyle"]; menu.Items.Add(menuItem); }