3

XAML でオブジェクトをインスタンス化し、これらのインスタンスを再利用したいと考えています。私はそれが単純であるべきだと思いますが、私は立ち往生しています.おそらく明らかなものが欠けています.

猫を別の部屋に追加したいとします (部屋には猫型のオブジェクトを含む ObservableCollection があります)。UserControl.Resources で ObjectDataProviders を作成します。

<ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}">
    <ObjectDataProvider.ConstructorParameters>
        <System:String>Tom</System:String>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Cat2" ObjectType="{x:Type local:Cat}">
    <ObjectDataProvider.ConstructorParameters>
        <System:String>Garfield</System:String>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="Cat3" ObjectType="{x:Type local:Cat}">
    <ObjectDataProvider.ConstructorParameters>
        <System:String>Furball</System:String>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

私の UserControl では、猫を部屋に追加したいと考えています。

<local:Room x:Name="Room1">
    <local:Room.Cats>

    </local:Room.Cats>
<local:Room>
<local:Room x:Name="Room2">
    <local:Room.Cats>

    </local:Room.Cats>
<local:Room>

Cat インスタンスを ObservableCollection Room.Cats に追加するための構文は何ですか? たとえば、Cat1 と Cat2 を Room1 に追加し、Cat2 と Cat3 を Room2 に追加したいとします。私は完全に間違った道を進んでいますか?

4

3 に答える 3

6

個々のインスタンスをあなたがしようとしている方法で再利用するのは難しいです。これは、XAML で単一のオブジェクトを参照する一般的な方法はStaticResourceマークアップ拡張機能を使用するためであり、そのマークアップ拡張機能を使用してプロパティ値を設定することしかできません。

Catしたがって、 type のプロパティをa のインスタンスに簡単に設定できますCat

<Room Cat="{StaticResource Cat1}"/>

ただし、プロパティを設定してコレクションを設定することはできません。

驚くべきことに、その答えは、オブジェクトを s でラップするのではなく、XAML で直接インスタンス化することですObjectDataProvider。を引き続き使用しますがObjectDataProvider、次のように異なります。

<Window x:Class="ObjectDataProviderDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:local="clr-namespace:ObjectDataProviderDemo" 
        xmlns:Collections="clr-namespace:System.Collections;assembly=mscorlib" 
        Title="MainWindow" 
        Height="350" 
        Width="525">
    <Window.Resources>
        <local:Cat x:Key="Tom" Name="Tom"/>
        <local:Cat x:Key="Garfield" Name="Garfield"/>
        <local:Cat x:Key="Furball" Name="Furball"/>
        <Collections:ArrayList x:Key="CatList1">
            <ObjectDataProvider ObjectInstance="{StaticResource Tom}" />
            <ObjectDataProvider ObjectInstance="{StaticResource Garfield}" />
            <ObjectDataProvider ObjectInstance="{StaticResource Furball}" />
        </Collections:ArrayList>
        <Collections:ArrayList x:Key="CatList2">
            <ObjectDataProvider ObjectInstance="{StaticResource Tom}" />
            <ObjectDataProvider ObjectInstance="{StaticResource Furball}" />
        </Collections:ArrayList>
        <DataTemplate x:Key="CatTemplate">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </Window.Resources>
    <StackPanel>
        <ListBox ItemsSource="{StaticResource CatList1}" 
                 ItemTemplate="{StaticResource CatTemplate}"/>
        <ListBox ItemsSource="{StaticResource CatList2}"
                 ItemTemplate="{StaticResource CatTemplate}" />
    </StackPanel>
</Window>
于 2010-10-01T19:49:08.327 に答える
3

Heinzi と Robert Rossney からのフィードバックに基づいて、XAML とコード ビハインドでアクセスできる ObservableCollection で動作する次のソリューションを思い付きました。

コードでは、ObservableCollection を拡張して XAML で使用できるようにしました (これは XAML 2009 では不要になります)。

public class CatObservableCollection : ObservableCollection<Cat> { }

UserControl.Resources の XAML で、Cats をインスタンス化します。

<local:Cat x:Key="Tom" Name="Tom"/>
<local:Cat x:Key="Garfield" Name="Garfield"/>
<local:Cat x:Key="Furball" Name="Furball"/>

コレクション:

<local:CatObservableCollection x:Key="Room1Collection">
    <StaticResourceExtension ResourceKey="Tom"/>
    <StaticResourceExtension ResourceKey="Garfield"/>
</local:CatObservableCollection>
<local:CatObservableCollection x:Key="Room2Collection">
    <StaticResourceExtension ResourceKey="Garfield"/>
    <StaticResourceExtension ResourceKey="Furball"/>
</local:CatObservableCollection>

部屋は次のように定義されます。

<local:Room x:Name="Room1" Cats="{StaticResource Room1Collection}"/>
<local:Room x:Name="Room2" Cats="{StaticResource Room2Collection}"/>

Room.Cats は ObservableCollection<Cat> です

于 2010-10-04T09:25:44.993 に答える
0

非常に具体的なニーズについては、ジェネリックを使用する必要があります。ジェネリックを宣言的に使用するには、x:TypeArguments Directiveを使用する必要があります。TypeArguments ディレクティブは、ルート要素でのみ使用できます。そのため、ルース XAML ファイルを使用する必要があります。Loose XAML ファイルは、次を使用して読み取ることができます。System.Windows.Markup.XamlReader.Load(Stream Stream) method

Cat.cs :

using System;

namespace WpfCollection._3840371
{
    public class Cat
    {
        public Cat() { }

        public Cat(String name, String color) { Name = name; Color = color; }

        public String Name { get; set; }
        public String Color { get; set; }
    }
}

Room.cs :

using System;
using System.Collections.ObjectModel;

namespace WpfCollection._3840371
{
    public class Room<T> where T : System.Windows.Data.ObjectDataProvider
    {
        public Room()
        {
            Cats = new ObservableCollection<T>();
        }

        public ObservableCollection<T> Cats { get; set; }
    }
}

ウィンドウ クラス :

namespace WpfCollection._3840371
{
    /// <summary>
    /// Interaction logic for Win3840371.xaml
    /// </summary>
    public partial class Win3840371 : Window
    {
        public Win3840371()
        {
            InitializeComponent();

            Room<ObjectDataProvider> kitchenRoom;
            using (FileStream fs = new FileStream(@"3840371/roomcats.txt", FileMode.Open))
            {
                kitchenRoom = (Room<ObjectDataProvider>)XamlReader.Load(fs);
            }

            foreach (ObjectDataProvider o in kitchenRoom.Cats)
                Debug.WriteLine(((Cat)o.Data).Name + " : " + ((Cat)o.Data).Color);
        }
    }
}

したがって、XAML コードを含む .txt ファイルは次のようになります。

<local:Room 
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            xmlns:System="clr-namespace:System;assembly=mscorlib"
            xmlns:local="clr-namespace:WpfCollection._3840371;assembly=WpfCollection"
            x:Key="UpperRoom" x:TypeArguments="ObjectDataProvider">
            <local:Room.Cats>
                <ObjectDataProvider x:Key="Cat1" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Tom</System:String>
                        <System:String>Red</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
                <ObjectDataProvider x:Key="Cat2" ObjectType="{x:Type local:Cat}">
                    <ObjectDataProvider.ConstructorParameters>
                        <System:String>Rubia</System:String>
                        <System:String>Brown</System:String>
                    </ObjectDataProvider.ConstructorParameters>
                </ObjectDataProvider>
            </local:Room.Cats>
        </local:Room>
于 2015-09-12T12:28:55.563 に答える