1

ユーザーがツールボックスからいくつかのオブジェクトをドラッグ/ドロップできるようにしています。もちろん、それぞれobjectに一意の ID があります。gridオブジェクトが使用されるとすぐに、またはに配置されたとしましょう。canvasそのプロパティを表示する必要があるため、各オブジェクトが独自のプロパティを保持できるオブジェクトの配列が必要です。

複数のオブジェクトを処理するクラスを実装し、各オブジェクトが 10 個のプロパティを保持できるようにする方法について、アドバイスと方向性を教えてください。

4

2 に答える 2

1

最善の解決策は、PropertyGridコントロールを使用することです。アプリケーションは Visual Studio に似ており、実装もそれに似ています。

あなたが持っている利用可能なオプションについては、このSOの質問を見てPropertyGridください - Is there a Property Dialog control that i can use in my WPF App?

これで、各コントロールのクラスを定義し、そのコントロールの通常の CLR プロパティを宣言できるようになりました。PropertyGrid に表示したくないプロパティは、BrowsableAttributeでマークすることができ、PropertyGrid はそれを尊重します。

表示されるプロパティをより細かく制御したい場合は、独自のカスタム 属性を作成し、 PropertyGrid 実装を変更してその属性を使用し、この属性でマークされたプロパティを表示することができます。

于 2012-06-16T12:03:13.477 に答える
1

複数のオブジェクトを処理するクラスを実装する方法について、アドバイスと方向性を教えてください。各オブジェクトは、たとえば 10 個のプロパティを保持できますか?

そのようなクラスを実装する必要はありません。この問題を処理する方法は、ツールボックスToolboxItem内のすべてのアイテムに共通のプロパティと機能のみを公開する、ツールボックス内のすべてのオブジェクト (たとえば) に共通の基本クラスを用意することです。

public abstract class ToolboxItem
{
    public string Name { get; set; }
    public Point Position { get; set; }
}

次に、このクラス EG TextToolboxItemand RectangleToolboxItem(または必要なもの) から特定のアイテムを派生させることができます。派生クラスは、必要なプロパティのみを公開できます。

public class TextToolboxItem : ToolboxItem
{
    public string Text { get; set; }
}

public class RectangleToolboxItem : ToolboxItem
{
    public Rect Bounds { get; set; }
}

これらを保存するには、次のような一般的なコレクションを使用できます。

ObservableCollection<ToolboxItem> items = new ObservableCollection<ToolboxItems>();

アイテムが派生する限り、ToolboxItemそれらはすべて単一のコレクション内に保持でき、個々のプロパティはすべて WPF のデータ バインディング機能を使用してバインドできます。

次に、次の方法でデータを作成して公開できます。

public partial class MainWindow : Window
{
    private ObservableCollection<ToolboxItem> items;

    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;

        items = new ObservableCollection<ToolboxItem>
        {
            new TextToolboxItem { Name = "primaryText", 
                                  Text = "Hello world", 
                                  Position = new Point(40, 130) },
            new TextToolboxItem { Name = "secondaryText", 
                                  Text = "Hello world (again)", 
                                  Position = new Point(200, 30) },
            new RectangleToolboxItem { Position = new Point(50,300), 
                                       Name = "Rect1", 
                                       Bounds = new Rect(0, 0, 150, 85) },
        };
    }

    public ObservableCollection<ToolboxItem> Items { get { return items; } }
}

この情報をユーザー インターフェイスに表示するには、次のようにします。

  • グリッドを使用して、ビューを 2 つのセクションに分割します。1 つ目は選択した項目のプロパティが表示される場所で、2 つ目は「デザイン サーフェイス」が表示されます。
  • を使用して、選択ContentPresenterしたアイテムのプロパティを表示します。
  • ListBoxカスタムItemsPanelとを使用してItemContainerStyle、アイテムをデザイン サーフェイスに「描画」します。
  • aDataTemplateを使用して、「プロパティ グリッド」と「デザイン サーフェイス」の両方で各アイテムをレンダリングする方法を WPF に指示します (この投稿では、オブジェクトごとに異なる を使用する方法について説明しDataTemplateます)。

これを実現するために必要な xaml を以下に示します。

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:this="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="3*" />
        <ColumnDefinition Width="7*" />
    </Grid.ColumnDefinitions>

    <ContentPresenter Content="{Binding ElementName=listBox, Path=SelectedItem}"
                      Margin="5">
        <ContentPresenter.Resources>
            <DataTemplate DataType="{x:Type this:TextToolboxItem}">
                <StackPanel>
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding Position}"/>
                    <TextBlock Text="{Binding Text}"/>
                </StackPanel>
            </DataTemplate>
            <DataTemplate DataType="{x:Type this:RectangleToolboxItem}">
                <StackPanel>
                    <TextBlock Text="{Binding Name}"/>
                    <TextBlock Text="{Binding Position}"/>
                    <TextBlock Text="{Binding Bounds}"/>
                </StackPanel>
            </DataTemplate>
        </ContentPresenter.Resources>
    </ContentPresenter>

    <ListBox x:Name="listBox" Grid.Column="1"
             Margin="5" ItemsSource="{Binding Items}">
        <ListBox.Resources>
            <DataTemplate DataType="{x:Type this:TextToolboxItem}">
                <TextBox Text="{Binding Text}"
                         Margin="10"/>
            </DataTemplate>
            <DataTemplate DataType="{x:Type this:RectangleToolboxItem}">
                <Rectangle Width="{Binding Bounds.Width}"
                           Height="{Binding Bounds.Height}"
                           Stroke="DarkRed" Fill="Pink"/>
            </DataTemplate>
        </ListBox.Resources>

        <ListBox.ItemContainerStyle>
            <Style>
                <Setter Property="Canvas.Left" Value="{Binding Position.X}"/>
                <Setter Property="Canvas.Top" Value="{Binding Position.Y}"/>
            </Style>
        </ListBox.ItemContainerStyle>

        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <Canvas />
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
    </ListBox>

</Grid>

最終結果は次のようになります。

ここに画像の説明を入力

選択した項目のプロパティがウィンドウの左側のセクションに表示されていることに注意してください。

現在、このソリューションは非常に粗雑ですが、これをさらに開発するための出発点を示しています。改善のためのアイデアは次のとおりです。

  • MVVM に準拠するように、コードを viewModel にリファクタリングします。
  • 「デザイン サーフェイス」でアイテムのドラッグ アンド ドロップを処理します。
  • プロパティ グリッドの「ContentPresenter」を変更して、選択したオブジェクトのプロパティを表示および編集するためのより豊富なサポートを提供します。
于 2012-06-16T13:04:59.437 に答える