0

ビューモデルがあります

 public class ViewModel:ViewModelObject
{
    public ViewModel()
    {
        ProjectionDataElementList = new ObservableCollection<ProjectionDataElement>();
    }

    public ObservableCollection<ProjectionDataElement> ProjectionDataElementList { get; set; }

    private ProjectionDataElement _currentSelectedProjectionDataElement;

    public ProjectionDataElement CurrentSelectedProjectionDataElement
    {
        get 
        { 
            return _currentSelectedProjectionDataElement; 
        }
        set 
        { 
            _currentSelectedProjectionDataElement = value;
            OnPropertyChanged("CurrentSelectedProjectionDataElement");
        }
    }

}

ProjectorDisplayControl というコントロール

<UserControl x:Class="Fast_Project.ProjectorDisplayControl"
         ..................>
<Viewbox>
    <StackPanel>
        <TextBlock Text="{Binding Path=TextBody}"/>
    </StackPanel>
</Viewbox>

    public partial class ProjectorDisplayControl : UserControl
{

    public ProjectorDisplayControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty ProjectedDataProperty = DependencyProperty.Register("ProjectedData", typeof(ProjectionDataElement), typeof(ProjectorDisplayControl),
            new PropertyMetadata(new PropertyChangedCallback((objectInstance, arguments) =>
            {
                ProjectorDisplayControl projectorDisplayControl = (ProjectorDisplayControl)objectInstance;
                projectorDisplayControl._projectedData = (ProjectionDataElement)arguments.NewValue;
            })));

    public ProjectionDataElement ProjectedData
    {
        get
        {
            return (ProjectionDataElement)GetValue(ProjectedDataProperty);
        }
        set
        {
            SetValue(ProjectedDataProperty, value);
        }
    }


    private ProjectionDataElement _projectedData
    {
        get
        {
            return this.DataContext as ProjectionDataElement;
        }
        set
        {
            this.DataContext = value;
        }
    }
}

このコントロールは 2 つの場所で使用されます。

最初の場所は、うまく機能する ListBox にあります。

<ListBox Grid.Column="0" ItemsSource="{Binding Path=ProjectionDataElementList}" Name="projectedDataListBox" 
             SelectedItem="{Binding Path=CurrentSelectedProjectionDataElement, UpdateSourceTrigger=PropertyChanged}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <Border BorderThickness="1" BorderBrush="Black">
                        <controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding}"/>
                    </Border>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

2 番目は、ViewModel オブジェクトを使用してフォームの DataContext を設定したフォームの上にあります。ProjectorDisplayControl が ViewModel で CurrentSelectedProjectionDataElement を消費するようにするには、次のようにする必要があります。

<Window x:Class="Fast_Project.DisplayWindow"
    ................>
<Viewbox>
    <StackPanel>
        <controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding CurrentSelectedProjectionDataElement}"/>
    </StackPanel>
</Viewbox>

このコードでは、次の 2 つのバインド エラーが発生します。

System.Windows.Data エラー: 40: BindingExpression パス エラー: 'TextBody' プロパティが 'object' ''ViewModel' (HashCode=2512406)' に見つかりません。BindingExpression:Path=TextBody; DataItem='ViewModel' (HashCode=2512406); ターゲット要素は 'TextBlock' (Name='') です。ターゲット プロパティは 'Text' (タイプ 'String') です

System.Windows.Data エラー: 40: BindingExpression パス エラー: 'CurrentSelectedProjectionDataElement' プロパティが 'object' ''ProjectionDataElement' (HashCode=37561097)' に見つかりません。BindingExpression:Path=CurrentSelectedProjectionDataElement; DataItem='ProjectionDataElement' (HashCode=37561097); ターゲット要素は 'ProjectorDisplayControl' (Name='_projectorDisplay') です。ターゲット プロパティは 'ProjectedData' (タイプ 'ProjectionDataElement') です。

DataContext を設定する ProjectorDisplayControl のプライベート プロパティ _projectedData のセッターを見ると、最初に有効な値が設定され、次に null に設定されることがわかります。

単一の ProjectorDisplayControl を保持する DisplayWindow で、CurrentSelectedProjectionDataElement へのバインディングを削除すると、最初のバインディング エラー メッセージのみが表示されます。

<Viewbox>
    <StackPanel>
        <controls:ProjectorDisplayControl x:Name="_projectorDisplay" />
    </StackPanel>
</Viewbox>

最初のバインディング エラーは、DisplayWindow の DataContext が設定されているときに、ProjectorDisplayControl の DataContext が ViewModel オブジェクトで設定されているように感じさせます。しかし、私が読んだことから、コントロールは、設定しない限り、親ウィンドウと同じデータ コンテキストを共有しません。

2 番目のエラー メッセージが示すように、DisplayWindow の ProjectorDisplayControl.ProjectedData のバインディング パスを ProjectionDataElement オブジェクトのように処理しました。

<Viewbox>
    <StackPanel>
        <controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding }"/>
    </StackPanel>
</Viewbox>

それから私に言います:

タイプ 'Fast_Project.ViewModel' と 'Fast_Project.ProjectionDataElement' の間で '一方向' の変換を実行するための既定のコンバーターを作成できません

そもそも思っていたように、本当にViewModelオブジェクトだったように...

とにかく、私の問題の根本は、ProjectorDisplayControl が ViewModel オブジェクトに設定された DataContext をどのように見るかにあると思われます。私がどこを台無しにしたか誰か見ますか?

ご協力ありがとうございました!


解決策は次のとおりです。


プロジェクター表示制御

        <StackPanel>
        <TextBlock Text="{Binding Path=ProjectedData.TextBody, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:ProjectorDisplayControl}}}"/>
    </StackPanel>

表示ウィンドウ

<StackPanel>
        <controls:ProjectorDisplayControl x:Name="_projectorDisplay" ProjectedData="{Binding Path=ViewModel.CurrentSelectedProjectionDataElement, 
            RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type controls:DisplayWindow}}}"/>
    </StackPanel>
4

1 に答える 1

0

子コントロールは、親から Dependency プロパティ値 (この場合は DataContext) を継承します。itemTempalte 内で UserControl を使用している場合、各項目の DataContext はすでに ProjectionDataElement であるため、コントロールの DataContext は ProjectionDataElement に設定されます。

親内でコントロールを使用している場合、そのコントロールはその DataContext を継承します。

問題は、ProjectedData プロパティをコントロールに設定し、その中で使用していないことです。各コントロールを ProjectedData に設定された値にバインドする必要がある場合は、次のようにバインディングを更新する必要があります。

<UserControl x:Class="Fast_Project.ProjectorDisplayControl"
         ..................>
<Viewbox>
    <StackPanel>
        <TextBlock Text="{Binding Path=ProjectedData.TextBody, RelativeSource={RelativeSource Self}"/>
    </StackPanel>

2番目のエラーについては、そのウィンドウの DataContext を ProjectionDataElement に設定する必要があるため、そのウィンドウ内で検索しています。

于 2013-09-26T02:27:31.990 に答える