6

ListBox を含む WPF ウィンドウがあります。ItemsSource は、ビュー モデルのプロパティにバインドされます。

<Window x:Class="SimpleWpfApp.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525"
        DataContext="{Binding MainWindowViewModel, Source={StaticResource Locator}}">
  <DockPanel>
    <ListBox ItemsSource="{Binding SomeThings}" />
  </DockPanel>
</Window>

ビュー モデルのプロパティは、カスタム インターフェイスの監視可能なコレクションです。ISomeInterface. インターフェイスは非常に単純で、ToString をさらにオーバーライドする SomeClass によって実装されます。

public class MainWindowViewModel
{
  public ObservableCollection<ISomeInterface> SomeThings
  {
    get
    {
      var list = new List<ISomeInterface>
      {
        new SomeClass {Value = "initialised"},
        new SomeClass {Value = "in"},
        new SomeClass {Value = "code"}
      };

      return new ObservableCollection<ISomeInterface>(list);
    }
  }
}

public interface ISomeInterface
{
  string Value { get; }
}

public class SomeClass : ISomeInterface
{
  public string Value { get; set; }

  public override string ToString() => Value;
}

Visual Studio 2015 または Blend でウィンドウを表示すると、すべてが期待どおりです。ToString が呼び出され、ListBox が設定されます。

ブレンドのスクリーンショット

デザイン モードで使用する XAML デザイン データを作成しました。SampleData というディレクトリに設計データを追加しました。最初の DataContext のすぐ下のウィンドウ XAML に、デザイン datacontext ステートメントを追加します。

d:DataContext="{d:DesignData Source=/SampleData/Data.xaml}"

これはうまくいきません。ソース パスに何を使用しても、Visual Studio と Blend は「ファイルまたはプロジェクト項目が見つかりません」と報告します。/SampleData/Data.xaml、SampleData/Data.xaml、../SampleData/Data.xaml、./../SampleData/Data.xaml を試しました

Visual Studio と Blend は、Data.xaml を SampleData ディレクトリからプロジェクト ルートに移動した場合にのみ検出します。次に、ソース パス /Data.xaml または Data.xaml を使用して参照できます。/ を前に付けずに Data.xaml を使用すると、Visual Studio と Blend はファイルが見つからないと報告しますが、とにかく見つけます。

私の最初の質問は..サブディレクトリでサンプルデータを使用できますか? もしそうなら、どのように?

プロジェクト ルートで Data.xaml を正常に参照した後、ウィンドウがオーバーライドされた ToString を呼び出していないため、クラス名のリストが表示されます。リストには設計データと同じ数のアイテムが含まれているため、設計データを使用しているように見えます。

私の 2 番目の質問は..オブジェクトがコードからインスタンス化されている場合に、オーバーライドされた ToString がここで呼び出されないのはなぜですか?

アイテム テンプレートを指定することで、目的の結果が得られることを認識しています。

<ListBox ItemsSource="{Binding SomeThings}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Value}"/>
    </DataTemplate>
  </ListBox.ItemTemplate>
</ListBox>

サンプル アプリケーションの完全なソースは、github で入手できます。

https://github.com/DangerousDarlow/WpfDesignData

アップデート

答えてくれたjstreetに感謝します。サブディレクトリにあるdata.xamlのファイルプロパティを変更したところ、デザインデータとして使えるようになりました。私は以前にこれを試したことがあると思っていましたが、間違っているに違いありません。

ToString が呼び出されているのをまだ見ていません。ビュー モデル プロパティをList<object>andに変更しようとしList<ISomeInterface>ましたが、どちらも object.ToString; に呼び出されました。クラス名の表示から推測されます。とにかく ToString を使用しないので、この時点で見るのをやめて、表示したいプロパティにバインドします。ただし、動作の違いを説明することは良いでしょう。

Visual Studio 2015 コミュニティ エディションを使用しています。

4

1 に答える 1

5

これが実際のサンプルコードです。この記事 - MSDNを参照してください。

特に、 VS プロジェクトでData.xamlファイル (私の場合はDictionary1.xaml )のプロパティを設定する方法に注意してください。

ここに画像の説明を入力

SomeThingsまた、ルート オブジェクト(私の場合はSomeClasses )の作成方法にも注意してください。

コレクションの場合、ルート オブジェクトは、コレクションまたはジェネリック コレクションから派生した ArrayList またはカスタム型にすることができます...

XAML:

<Window x:Class="WpfApplication277.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApplication277"
    d:DataContext="{d:DesignData Source=/SampleData/Dictionary1.xaml}"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView ItemsSource="{Binding}"></ListView>
</Grid>

Dictionary1.xaml:

SampleDataVS プロジェクトのフォルダーを右クリックし、 Add\New Item\WPF\Resource Dictionaryを選択して、その内容をデザイン データに置き換えます。これにより、設計データをサブフォルダーに配置できるようになります。

<m:SomeClasses xmlns:m="clr-namespace:WpfApplication277">
<m:SomeClass Value="design data 1">
</m:SomeClass>
<m:SomeClass Value="design data 2">
</m:SomeClass>
<m:SomeClass Value="design data 3">
</m:SomeClass>

一部のクラス: List<SomeClass>機能しませんでした!

public class SomeClasses : List<Object>
{
    public SomeClasses() { }
}

一部のクラス:

public class SomeClass : ISomeInterface
{
    public string Value { get; set; }

    public override string ToString() => string.Format("ToString() : {0}",Value);
}

ToString()間違いなく呼び出されていることに注意してください:

ここに画像の説明を入力

于 2016-09-10T11:06:03.957 に答える