Expression Blend的“编辑模板”功能是否有Visual Studio(或免费软件)等价物?

时间:2009-09-30 20:57:45

标签: wpf visual-studio xaml templates expression-blend

在Expression Blend中,您可以在“对象和时间轴”面板中查看和编辑对象的控件模板。我想知道在Visual Studio中是否有相同的功能,或者是否有免费(或非常便宜)的东西我可以下载,这将允许我这样做。

DataGrid执行此操作会产生以下结果:

<Style x:Key="DataGridStyle1" TargetType="{x:Type Custom:DataGrid}">
  ...
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type Custom:DataGrid}">
      ...
      </ControlTemplate>
    </Setter.Value>
  </Setter>
  <Style.Triggers>
    <Trigger Property="IsGrouping" Value="True">
      <Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
    </Trigger>
  </Style.Triggers>
</Style>

...当然被替换为setter和控件模板的内容。)

如果要为控件创建自定义样式和模板,这是一个非常有用的起点。看起来你可以在Blend in Studio中做任何你可以做的事情,但是这个让我望而却步。有什么想法吗?

修改

我也很好奇这个功能是否在Visual Studio 2010中。任何人都知道吗?

1 个答案:

答案 0 :(得分:0)

The SimpleStyles project

尝试我认为它会是一样的。它为每个控件提供了最简单的模板,因此您可以将其用作跳转点。

获取模板的项目代码:

C#

using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Xml;

namespace ControlTemplateBrowser
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        private System.Windows.Forms.NotifyIcon icon;
        private WindowState _storedWindowState;
        private bool _ballonShownOnce = false;

        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            Type controlType = typeof(Control);

            List<Type> derivedTypes = new List<Type>();

            // Search all the types in the assembly where the Control class is defined
            Assembly assembly = Assembly.GetAssembly(typeof(Control));

            foreach (Type type in assembly.GetTypes())
            {
                // Only add a type of the list if it's a Control, a concrete class, and public.
                if (type.IsSubclassOf(controlType) && !type.IsAbstract && type.IsPublic)
                {
                    derivedTypes.Add(type);
                }
            }

            // Sort the types. The custom TypeComparer class orders types alphabetically by type name.
            derivedTypes.Sort(new TypeComparer());
            lstTypes.ItemsSource = derivedTypes;

            SetupTrayIcon();
        }

        private void lstTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                // Get the selected type.
                Type type = (Type)lstTypes.SelectedItem;

                // Instantiate the type
                ConstructorInfo info = type.GetConstructor(System.Type.EmptyTypes);
                Control control = (Control)info.Invoke(null);

                // Add it to the grid (but keep it hidden)
                control.Visibility = Visibility.Collapsed;
                grid.Children.Add(control);

                // Get the template.
                ControlTemplate template = control.Template;

                // Get the XAML for the template.
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                StringBuilder sb = new StringBuilder();
                XmlWriter writer = XmlWriter.Create(sb, settings);
                XamlWriter.Save(template, writer);

                // Display the template
                txtTemplate.Text = sb.ToString();
                grid.Children.Remove(control);
            }
            catch (Exception err)
            {
                txtTemplate.Text = "<< Error generating template: " + err.Message + ">>";
            }
        }

        #region System tray icon code

        private void SetupTrayIcon()
        {
            // Add system tray icon
            icon = new System.Windows.Forms.NotifyIcon();
            icon.Icon = new System.Drawing.Icon("appIcon.ico");
            icon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;
            icon.BalloonTipTitle = "Minimized to tray";
            icon.BalloonTipText = "Click icon to maximize.";
            icon.Visible = false;
            icon.Click += new EventHandler(icon_Click);
        }

        private void icon_Click(object sender, EventArgs e)
        {
            Show();
            WindowState = _storedWindowState;
        }

        private void Window_StateChanged(object sender, EventArgs e)
        {
            if (WindowState == WindowState.Minimized)
            {
                Hide();
                if (icon != null)
                {
                    if (!_ballonShownOnce)
                    {
                        icon.ShowBalloonTip(2000);
                        _ballonShownOnce = true;
                    }
                }
            }
            else
                _storedWindowState = WindowState;
        }

        private void Window_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (icon != null)
                icon.Visible = !IsVisible;
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            icon.Visible = false;
            icon.Dispose();
            icon = null;
        }

        #endregion
    }

    public class TypeComparer : IComparer<Type>
    {
        #region IComparer<Type> Members

        public int Compare(Type x, Type y)
        {
            return String.Compare(x.Name, y.Name);
        }

        #endregion
    }

}

WPF:

<Window x:Class="ControlTemplateBrowser.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="WPF Control Template Browser" Height="600" Width="800" Loaded="Window_Loaded" Icon="/ControlTemplateBrowser;component/appIcon.png" Closed="Window_Closed" StateChanged="Window_StateChanged" IsVisibleChanged="Window_IsVisibleChanged">
    <Grid x:Name="grid" Margin="8">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <ListBox Grid.Column="0" x:Name="lstTypes" SelectionChanged="lstTypes_SelectionChanged">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding Name}" Margin="5,0" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <TextBox Grid.Column="1" x:Name="txtTemplate" Text="Select a control to see its template." VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" />
    </Grid>
</Window>

将其粘贴到项目中并执行必要的命名空间修改。我认为你需要修改的是这部分:

// Search all the types in the assembly where the Control class is defined
Assembly assembly = Assembly.GetAssembly(typeof(Control));

从不同的程序集中获取控件。如果你尝试了,以及它是如何进行的。