Share via


HOW TO:建立對話方塊屬性值編輯器

下列程式碼範例示範如何為 WPF Designer for Visual Studio 實作自訂對話方塊屬性值編輯器。如需完整的方案,請參閱 WPF 設計工具擴充性範例網站上的<對話方塊屬性值編輯器>範例 (英文)。 

範例

本主題示範如何建立對話方塊屬性值編輯器,這會在 [屬性] 視窗中按一下自訂 [FileName] 屬性時,顯示開啟檔案對話方塊。

using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows;

namespace CustomControlLibrary
{
    public partial class DemoControl : UserControl
    {
        public DemoControl()
        {
            InitializeComponent();
        }

        public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register(
            "FileName", 
            typeof(string), 
            typeof(DemoControl), 
            new PropertyMetadata("File name not set."));

        public string FileName
        {
            get
            {
                return (string)this.GetValue(FileNameProperty);
            }

            set
            {
                this.SetValue(FileNameProperty, value);
            }
        }
    }
}
<ResourceDictionary xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"
                    xmlns:Local="clr-namespace:CustomControlLibrary.Design"
                    x:Class="CustomControlLibrary.Design.EditorResources">

    <DataTemplate x:Key="FileBrowserInlineEditorTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TextBox Grid.Column="0" Text="{Binding StringValue}"/>
            <PropertyEditing:EditModeSwitchButton Grid.Column="1"/>
        </Grid>
    </DataTemplate>

</ResourceDictionary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CustomControlLibrary.Design
{
    using System.Windows;
    public partial class EditorResources : ResourceDictionary
    {
        public EditorResources()
            : base()
        {
            InitializeComponent();
        }
    }
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;
using Microsoft.Win32;

namespace CustomControlLibrary.Design
{
    public class FileBrowserDialogPropertyValueEditor : DialogPropertyValueEditor
    {
        private EditorResources res = new EditorResources();

        public FileBrowserDialogPropertyValueEditor()
        {
            this.InlineEditorTemplate = res["FileBrowserInlineEditorTemplate"] as DataTemplate;
        }

        public override void ShowDialog(
            PropertyValue propertyValue,
            IInputElement commandSource)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;

            if (ofd.ShowDialog() == true)
            {
                propertyValue.StringValue = ofd.FileName;
            }
        }
    }
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;

// The ProvideMetadata assembly-level attribute indicates to designers
// that this assembly contains a class that provides an attribute table. 
[assembly: ProvideMetadata(typeof(CustomControlLibrary.Design.Metadata))]
namespace CustomControlLibrary.Design
{
    // Container for any general design-time metadata to initialize.
    // Designers look for a type in the design-time assembly that 
    // implements IProvideAttributeTable. If found, designers instantiate 
    // this class and access its AttributeTable property automatically.
    internal class Metadata : IProvideAttributeTable 
    {
        // Accessed by the designer to register any design-time metadata.
        public AttributeTable AttributeTable
        {
            get 
            {
                AttributeTableBuilder builder = new AttributeTableBuilder();

                builder.AddCustomAttributes
                    (typeof(CustomControlLibrary.DemoControl),
                    "FileName",
                    PropertyValueEditor.CreateEditorAttribute(
                        typeof(FileBrowserDialogPropertyValueEditor)));

                return builder.CreateTable();
            }
        }
    }
}
<Window x:Class="WpfApplication1.MainWindow"
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:ccl="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"
    Title="MainWindow" Height="300" Width="300">
    <Grid>
        <ccl:DemoControl FileName="" />
    </Grid>
</Window>

編譯程式碼

在三個不同的組件中,編譯先前的範例程式碼。

編譯自訂控制項

  1. 在 Visual Studio 中,以 C# 建立名為 CustomControlLibrary 的新 WPF 使用者控制項程式庫專案。

  2. 將所有出現 "UserControl1" 的地方變更為 "DemoControl"。

  3. 將 DemoControl 類別中的現有程式碼替換成前面所列的程式碼。

  4. 建置方案。

編譯自訂對話方塊屬性值編輯器

  1. 在 Visual Studio 中,將名為 CustomControlLibrary.Design 的新 WPF 使用者控制項程式庫專案加入到方案中。

  2. 將專案的輸出路徑設定為 ".. \CustomControlLibrary\bin\Debug\"。

  3. 從專案中刪除 UserControl1.xaml 和 UserControl1.xaml.cs。

  4. 加入下列組件的參考。

    • Microsoft.Windows.Design.Extensibility

    • Microsoft.Windows.Design.Interaction

  5. 加入 CustomControlLibrary 專案的參考。

  6. 將名為 EditorResources 的資源字典加入至專案。

  7. 將 EditorResources.xaml 中的現有 XAML 替換成前面所列的 XAML。

  8. 將名為 EditorResources 的新類別加入到專案。

  9. 將 EditorResources 中的現有程式碼替換成前面所列的程式碼。

  10. 將名為 FileBrowserDialogPropertyValueEditor 的新類別加入到專案。

  11. 將 FileBrowserDialogPropertyValueEditor 類別中的現有程式碼替換成前面所列的程式碼。

  12. 將名為 Metadata 的新類別加入到專案。

  13. 將 Metadata 類別中的現有程式碼替換成前面所列的程式碼。

  14. 建置方案。

編譯測試應用程式

  1. 在 Visual Studio 中,將新的 WPF 應用程式專案加入到方案。

  2. 加入 CustomControlLibrary 組件或專案的參考。

  3. 在 MainWindow.xaml 的 [XAML] 檢視中,將現有 XAML 替換成前面所列的 XAML。

  4. 在 MainWindow.xaml.cs 中,將 InitializeComponent 的呼叫標記為註解。

  5. 重建方案。

  6. 按一下 [設計] 檢視中的 DemoControl 選取該項目。 您可能需要按一下設計工具頂端的資訊列,重新載入檢視。

  7. 在 [屬性] 視窗中,按一下 [FileName] 屬性旁邊的按鈕。

    [開啟] 對話方塊便會出現。

  8. 巡覽至檔案,然後按一下 [開啟]。

    檔案名稱會顯示在 [屬性] 視窗的 [FileName] 屬性中,且 FileName 屬性會指派在 [XAML] 檢視中。

請參閱

參考

ItemPolicy

PrimarySelectionPolicy

其他資源

進階擴充性概念

WPF 設計工具擴充性

WPF 設計工具擴充性範例