我正在开发一个可视工作室包来处理一些高级工作项复制方案。我想知道是否有人知道如何重现工作项上使用的树状“区域路径”和“迭代”控件,以便在我的加载项中使用?我正在使用WPF构建我的控件。
答案 0 :(得分:2)
该控件位于Microsoft.TeamFoundation.WorkItemTracking.Controls程序集中。它是WorkItemClassificationControl,但它是“内部”,这意味着你将无法引用它。我还与工作项跟踪客户团队的一位开发人员进行了交谈,他说该控件不是为在Team Explorer(我们的Visual Studio包)之外使用而设计的。
答案 1 :(得分:1)
这是互联网上非常痛苦的比特集合,因为我是WPF的新手,但我重新创建了它。我找到了ComboBox的原始XAML并修改如下:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:project="clr-namespace:Project.Utilities">
<LinearGradientBrush x:Key="TextBoxBorder"
StartPoint="0,0"
EndPoint="0,20"
MappingMode="Absolute">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#ABADB3"
Offset="0.05"/>
<GradientStop Color="#E2E3EA"
Offset="0.07"/>
<GradientStop Color="#E3E9EF"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush x:Key="ButtonNormalBackground"
StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#F3F3F3"
Offset="0"/>
<GradientStop Color="#EBEBEB"
Offset="0.5"/>
<GradientStop Color="#DDDDDD"
Offset="0.5"/>
<GradientStop Color="#CDCDCD"
Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonNormalBorder"
Color="#FF707070"/>
<Geometry x:Key="DownArrowGeometry">M 0 0 L 3.5 4 L 7 0 Z</Geometry>
<Style x:Key="ComboBoxReadonlyToggleButton"
TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle"
Value="true"/>
<Setter Property="IsTabStop"
Value="false"/>
<Setter Property="Focusable"
Value="false"/>
<Setter Property="ClickMode"
Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<theme:ButtonChrome Name="Chrome"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}"
SnapsToDevicePixels="true">
<Grid Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"
HorizontalAlignment="Right">
<Path Name="Arrow"
Margin="3,1,0,0"
Fill="Black"
Data="{StaticResource DownArrowGeometry}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</theme:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="true">
<Setter TargetName="Chrome"
Property="RenderPressed"
Value="true"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Arrow"
Property="Fill"
Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="4,4,21,4"
StrokeThickness="1"
Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"
StrokeDashArray="1 2"
SnapsToDevicePixels="true"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxEditableTextBox"
TargetType="{x:Type TextBox}">
<Setter Property="OverridesDefaultStyle"
Value="true"/>
<Setter Property="AllowDrop"
Value="true"/>
<Setter Property="MinWidth"
Value="0"/>
<Setter Property="MinHeight"
Value="0"/>
<Setter Property="FocusVisualStyle"
Value="{x:Null}"/>
<Setter Property="ScrollViewer.PanningMode"
Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled"
Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<ScrollViewer x:Name="PART_ContentHost"
Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
Background="Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ComboBoxToggleButton"
TargetType="{x:Type ToggleButton}">
<Setter Property="OverridesDefaultStyle"
Value="true"/>
<Setter Property="IsTabStop"
Value="false"/>
<Setter Property="Focusable"
Value="false"/>
<Setter Property="ClickMode"
Value="Press"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<theme:ButtonChrome Name="Chrome"
Width="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderPressed="{TemplateBinding IsPressed}"
RoundCorners="false"
SnapsToDevicePixels="true">
<Path Name="Arrow"
Margin="0,1,0,0"
Fill="Black"
Data="{StaticResource DownArrowGeometry}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</theme:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked"
Value="true">
<Setter TargetName="Chrome"
Property="RenderPressed"
Value="true"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter TargetName="Arrow"
Property="Fill"
Value="#AFAFAF"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="ComboBoxEditableTemplate"
TargetType="{x:Type ComboBox}">
<Grid Name="Placement"
SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Popup Name="PART_Popup"
Grid.ColumnSpan="2"
AllowsTransparency="true"
Placement="Bottom"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
<theme:SystemDropShadowChrome Name="Shdw"
Color="Transparent"
MinWidth="{Binding ElementName=Placement,Path=ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder"
BorderThickness="1"
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer Name="DropDownScrollViewer">
<Grid RenderOptions.ClearTypeHint="Enabled">
<Canvas Height="0" Width="0" HorizontalAlignment="Left" VerticalAlignment="Top">
<Rectangle
Name="OpaqueRect"
Height="{Binding ElementName=DropDownBorder,Path=ActualHeight}"
Width="{Binding ElementName=DropDownBorder,Path=ActualWidth}"
Fill="{Binding ElementName=DropDownBorder,Path=Background}" />
</Canvas>
<ItemsPresenter Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Contained"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
</ScrollViewer>
</Border>
</theme:SystemDropShadowChrome>
</Popup>
<theme:ListBoxChrome x:Name="Border"
Grid.ColumnSpan="2"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}"
RenderMouseOver="{TemplateBinding IsMouseOver}"
RenderFocused="{TemplateBinding IsKeyboardFocusWithin}"/>
<TextBox Name="PART_EditableTextBox"
Margin="{TemplateBinding Padding}"
Style="{StaticResource ComboBoxEditableTextBox}"
IsReadOnly="{Binding Path=IsReadOnly,RelativeSource={RelativeSource TemplatedParent}}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ToggleButton Grid.Column="1"
Style="{StaticResource ComboBoxToggleButton}"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocusWithin"
Value="true">
<Setter Property="Foreground"
Value="Black"/>
</Trigger>
<Trigger Property="IsDropDownOpen"
Value="true">
<Setter TargetName="Border"
Property="RenderFocused"
Value="true"/>
</Trigger>
<Trigger Property="HasItems"
Value="false">
<Setter TargetName="DropDownBorder"
Property="Height"
Value="95"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background"
Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false"/>
</Trigger>
<Trigger SourceName="PART_Popup"
Property="Popup.HasDropShadow"
Value="true">
<Setter TargetName="Shdw"
Property="Margin"
Value="0,0,5,5"/>
<Setter TargetName="Shdw"
Property="Color"
Value="#71000000"/>
</Trigger>
<Trigger SourceName="DropDownScrollViewer"
Property="ScrollViewer.CanContentScroll"
Value="false" >
<Setter TargetName="OpaqueRect"
Property="Canvas.Top"
Value="{Binding ElementName=DropDownScrollViewer, Path=VerticalOffset}" />
<Setter TargetName="OpaqueRect"
Property="Canvas.Left"
Value="{Binding ElementName=DropDownScrollViewer, Path=HorizontalOffset}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="Tree"
TargetType="{x:Type ComboBox}">
<Setter Property="FocusVisualStyle"
Value="{StaticResource ComboBoxFocusVisual}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background"
Value="{StaticResource ButtonNormalBackground}"/>
<Setter Property="BorderBrush"
Value="{StaticResource ButtonNormalBorder}"/>
<Setter Property="BorderThickness"
Value="1"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility"
Value="Auto"/>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility"
Value="Auto"/>
<Setter Property="Padding"
Value="4,3"/>
<Setter Property="ScrollViewer.CanContentScroll"
Value="true"/>
<Setter Property="ScrollViewer.PanningMode"
Value="Both"/>
<Setter Property="Stylus.IsFlicksEnabled"
Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ComboBox}">
<Grid Name="MainGrid"
SnapsToDevicePixels="true">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition MinWidth="{DynamicResource {x:Static SystemParameters.VerticalScrollBarWidthKey}}"
Width="0"/>
</Grid.ColumnDefinitions>
<Popup Name="PART_Popup"
AllowsTransparency="true"
Grid.ColumnSpan="2"
Placement="Bottom"
Margin="1"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
<theme:SystemDropShadowChrome Name="Shdw"
Color="Transparent"
MinWidth="{Binding ElementName=MainGrid,Path=ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder"
BorderThickness="1"
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">
<ScrollViewer Name="DropDownScrollViewer">
<TreeView x:Name="PART_TreeView" ItemsSource="{TemplateBinding ItemsSource}">
<i:Interaction.Behaviors>
<project:BindableSelectedItemBehavior SelectedItem="{Binding RelativeSource={RelativeSource AncestorType={x:Type ComboBox} }, Path=SelectedItem, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding ChildNodes}">
<TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</ScrollViewer>
</Border>
</theme:SystemDropShadowChrome>
</Popup>
<ToggleButton Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
Style="{StaticResource ComboBoxReadonlyToggleButton}"
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter IsHitTestVisible="false"
Margin="{TemplateBinding Padding}"
Content="{TemplateBinding SelectionBoxItem, Converter={project:PathConverter}}"
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger SourceName="PART_Popup"
Property="Popup.HasDropShadow"
Value="true">
<Setter TargetName="Shdw"
Property="Margin"
Value="0,0,5,5"/>
<Setter TargetName="Shdw"
Property="Color"
Value="#71000000"/>
</Trigger>
<Trigger Property="HasItems"
Value="false">
<Setter TargetName="DropDownBorder"
Property="Height"
Value="95"/>
</Trigger>
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
<Setter Property="Background"
Value="#FFF4F4F4"/>
</Trigger>
<Trigger Property="IsGrouping"
Value="true">
<Setter Property="ScrollViewer.CanContentScroll"
Value="false"/>
</Trigger>
<Trigger SourceName="DropDownScrollViewer"
Property="ScrollViewer.CanContentScroll"
Value="false" >
<Setter TargetName="PART_TreeView"
Property="Canvas.Top"
Value="{Binding ElementName=DropDownScrollViewer, Path=VerticalOffset}" />
<Setter TargetName="PART_TreeView"
Property="Canvas.Left"
Value="{Binding ElementName=DropDownScrollViewer, Path=HorizontalOffset}" />
</Trigger>
<Trigger Property="Tag">
<Setter Property="SelectedValue" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEditable"
Value="true">
<Setter Property="BorderBrush"
Value="{StaticResource TextBoxBorder}"/>
<Setter Property="Background"
Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="IsTabStop"
Value="false"/>
<Setter Property="Padding"
Value="3"/>
<Setter Property="Template"
Value="{StaticResource ComboBoxEditableTemplate}"/>
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
我还必须在IsDropDownOpen
上添加ComboBox
属性的行为和一些时髦的bug。
public class BindableSelectedItemBehavior : Behavior<TreeView>
{
public static readonly DependencyProperty SelectedItemProperty =
DependencyProperty.Register("SelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged));
public object SelectedItem
{
get { return (object)GetValue(SelectedItemProperty); }
set { SetValue(SelectedItemProperty, value); }
}
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectedItemChanged += this.OnTreeViewSelectedItemChanged;
}
protected override void OnDetaching()
{
base.OnDetaching();
if (this.AssociatedObject != null)
{
this.AssociatedObject.SelectedItemChanged += this.OnTreeViewSelectedItemChanged;
}
}
private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
var item = e.NewValue as TreeViewItem;
if (item != null)
{
item.SetValue(TreeViewItem.IsSelectedProperty, true);
}
}
private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
this.SelectedItem = e.NewValue;
var treeView = (TreeView)sender;
var control = (FrameworkElement)treeView.TemplatedParent;
ComboBox combo;
do
{
combo = control as ComboBox;
if (combo != null)
{
break;
}
}
while ((control = (FrameworkElement)control.TemplatedParent) != null);
if (combo == null)
{
return;
}
Dispatcher.BeginInvoke(new Action(() => combo.IsDropDownOpen = false)); // setting in other ways (XAML) wasn't working as expecting
}
}
并在实际控制中
...
<ComboBox Name="area" Style="{StaticResource Tree}"/>
...
<ComboBox Name="iteration" Style="{StaticResource Tree}"/>
和
背后的控制代码 private void UpdateAreasAndIterations(object sender, EventArgs e)
{
if (this.project.SelectedIndex <= 0)
{
this.area.Items.Clear();
this.iteration.Items.Clear();
}
else
{
var project = (Project)this.project.Items[this.project.SelectedIndex];
this.area.ItemsSource = project.AreaRootNodes;
this.iteration.ItemsSource = project.IterationRootNodes;
}
}