0

プロパティにデータバインディングがあるWPFコンボボックスを使用しようとしていSelecteItemます。ユーザーが新しい選択を選択すると、SelectedItem変更されますが、モデルが正しく更新されず、SelectionBoxItem(コンボボックスに表示される項目)は変更されません。

具体的には、次の2つの要素があります。

<ListView Name="lvNodes" ItemsSource="{Binding Path=Nodes}" SelectedItem="{Binding Path=CurrentNode, Mode=TwoWay}">
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding Path=Name}"/>
                            </StackPanel>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>

このリストビューは期待どおりに機能します。問題が発生しているコンボボックスは、次のように定義されます。

<ComboBox ItemsSource="{Binding Path=CameraViews}" SelectedItem="{Binding Path=CurrentNode.NodeInfo.Camera1, Converter={StaticResource EnsureBlank}, Mode=TwoWay}" Name="comboBoxTopCam" SelectionChanged="comboBoxTopCam_SelectionChanged">
                                <ComboBox.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Path=Name}"/>
                                    </DataTemplate>
                                </ComboBox.ItemTemplate>
                            </ComboBox>

したがって、ユーザーがListView(上記)からノードを選択すると、ComboBoxが更新され、そのノードが使用しているカメラが表示されます。

今、奇妙な行動。ユーザーがコンボボックスの新しいアイテムをクリックした場合、デバッガーを停止してプロパティを調べることができSelecteItemます。これは常に適切に設定されますが、CurrentNode.NodeInfo.Camera1プロパティは変更されず、「SelectionBox」に表示される文字列は変更されません。

しかし、それはさらに奇妙になります。ユーザーがComboBoxでそのような選択を行った後に(前に定義したListViewを使用して)ノードを切り替えると、ComboBoxは再び新しい値を表示しませんが、SelectedItemは正しいです。その後、ユーザーがListView AGAINで選択した項目を変更すると、正しい値の表示が開始され、ユーザーがコンボボックスを再度操作するまで問題ありません。

さて、ComboBoxが変更されてもモデルが更新されないことを先に述べたので、モデルを更新するイベントハンドラーを作成しました(これはComboBoxの定義で確認できます)。これは可能な限り定義されています

private void comboBoxTopCam_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        CameraViewInfo selCam = comboBoxTopCam.SelectedItem as CameraViewInfo;
        if (selCam != null)
        {
            OTNode selNode = lvNodes.SelectedItem as OTNode;

            if (selCam.Name == "None")
                selNode.NodeInfo.Camera1 = new CameraViewInfo();
            else
                selNode.NodeInfo.Camera1 = selCam; // <- This line affects the behavior
        }
    }

上記のリストでマークされた行をコメントアウトすると、ComboBoxはSelectionBoxに正しい項目を表示しますが、モデルを更新しません(たとえばCurrentNode.NodeInfo.Camera1、変更されません)。これは、lvNodes.SelectedItemORを使用するときに発生しますCurrentCamera(データバインドされたプロパティ)。どちらを使用しても違いはありません。

私はこれがかなり奇妙な問題であることを知っています、そして誰かがより多くの情報(データバインディングからのデバッグ出力、コンバーターのコード、等式演算子に関する情報など)が必要な場合はそれを説明できるように最善を尽くしましたイベントは、テキストだけでは理解するのが少し難しいので、必要に応じて奇妙な動作を示すビデオをアップロードする用意があります。

アップデート:

コンバーターのコード

public class EnsureBlankConterter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is CameraViewInfo)
        {
            if ((value as CameraViewInfo).Name == "")
            {
                return new CameraViewInfo()
                {
                    Name = "None"
                };
            }
        }

        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is CameraViewInfo)
        {
            if ((value as CameraViewInfo).Name == "None")
            {
                return new CameraViewInfo();
            }
        }

        return value;
    }
} 

を使用して出力をデバッグするPresentationTraceSource.High

ロード時:

System.Windows.Data Warning: 54 : Created BindingExpression (hash=45045097) for Binding (hash=10919470)
System.Windows.Data Warning: 56 :   Path: 'CurrentNode.NodeInfo.Camera1'
System.Windows.Data Warning: 60 : BindingExpression (hash=45045097): Attach to System.Windows.Controls.ComboBox.SelectedItem (hash=34909671)
System.Windows.Data Warning: 65 : BindingExpression (hash=45045097): Resolving source 
System.Windows.Data Warning: 68 : BindingExpression (hash=45045097): Found data context element: ComboBox (hash=34909671) (OK)
System.Windows.Data Warning: 76 : BindingExpression (hash=45045097): Activate with root item ConfigurationWindow (hash=22010384)
System.Windows.Data Warning: 105 : BindingExpression (hash=45045097):   At level 0 using cached accessor for ConfigurationWindow.CurrentNode: RuntimePropertyInfo(CurrentNode)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 0 with ConfigurationWindow (hash=22010384), using accessor RuntimePropertyInfo(CurrentNode)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): <null>
System.Windows.Data Warning: 104 : BindingExpression (hash=45045097):   Item at level 1 is null - no accessor
System.Windows.Data Warning: 101 : BindingExpression (hash=45045097): Replace item at level 2 with {NullDataItem}
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value {DependencyProperty.UnsetValue}
System.Windows.Data Warning: 86 : BindingExpression (hash=45045097): TransferValue - using fallback/default value <null>
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value <null>
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097):   At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 1 with OTNode (hash=59090892), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=59090892) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=34742292)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097):   At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 2 with OTNodeInfo (hash=34742292), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 2 from OTNodeInfo (hash=34742292) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 80 : BindingExpression (hash=45045097): TransferValue - user's converter produced CameraViewInfo (hash=29245900)
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value CameraViewInfo (hash=29245900)

選択ボックスに表示されなかったコンボボックスで選択を行った後:

System.Windows.Data Warning: 88 : BindingExpression (hash=45045097): Update - got raw value CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 90 : BindingExpression (hash=45045097): Update - user's converter produced CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 92 : BindingExpression (hash=45045097): Update - using final value CameraViewInfo (hash=7936647)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=59090892)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=59090892) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=22129877)

ListViewを新しいノードに切り替えても、選択ボックスは更新されませんでした。

System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=63206919)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 0 from ConfigurationWindow (hash=22010384) using RuntimePropertyInfo(CurrentNode): OTNode (hash=63206919)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097):   At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 1 with OTNode (hash=63206919), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 1 from OTNode (hash=63206919) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=35582358)
System.Windows.Data Warning: 106 : BindingExpression (hash=45045097):   At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=45045097): Replace item at level 2 with OTNodeInfo (hash=35582358), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=45045097): GetValue at level 2 from OTNodeInfo (hash=35582358) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 78 : BindingExpression (hash=45045097): TransferValue - got raw value CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 80 : BindingExpression (hash=45045097): TransferValue - user's converter produced CameraViewInfo (hash=49590542)
System.Windows.Data Warning: 87 : BindingExpression (hash=45045097): TransferValue - using final value CameraViewInfo (hash=49590542)

DIDが選択ボックスを更新するリストビューを使用してノードを切り替えた後、次のようになります。

System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 0 from ConfigurationWindow (hash=63245828) using RuntimePropertyInfo(CurrentNode): OTNode (hash=8023662)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 0 from ConfigurationWindow (hash=63245828) using RuntimePropertyInfo(CurrentNode): OTNode (hash=8023662)
System.Windows.Data Warning: 106 : BindingExpression (hash=51217614):   At level 1 - for OTNode.NodeInfo found accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 102 : BindingExpression (hash=51217614): Replace item at level 1 with OTNode (hash=8023662), using accessor ReflectPropertyDescriptor(NodeInfo)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 1 from OTNode (hash=8023662) using ReflectPropertyDescriptor(NodeInfo): OTNodeInfo (hash=21425964)
System.Windows.Data Warning: 106 : BindingExpression (hash=51217614):   At level 2 - for OTNodeInfo.Camera1 found accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 102 : BindingExpression (hash=51217614): Replace item at level 2 with OTNodeInfo (hash=21425964), using accessor ReflectPropertyDescriptor(Camera1)
System.Windows.Data Warning: 99 : BindingExpression (hash=51217614): GetValue at level 2 from OTNodeInfo (hash=21425964) using ReflectPropertyDescriptor(Camera1): CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 78 : BindingExpression (hash=51217614): TransferValue - got raw value CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 80 : BindingExpression (hash=51217614): TransferValue - user's converter produced CameraViewInfo (hash=6049320)
System.Windows.Data Warning: 87 : BindingExpression (hash=51217614): TransferValue - using final value CameraViewInfo (hash=6049320)
4

3 に答える 3

1

私はあなたの問題はあなたがバインドしている方法にあると思いますSelectedItem

<ComboBox ...
    SelectedItem="{Binding Path=CurrentNode.NodeInfo.Camera1, 
        Converter={StaticResource EnsureBlank}, Mode=TwoWay}"  ...

メモリが正しく機能する場合、フォーカスが失われた場合にのみ(デフォルトで)更新をプッシュするSelectedItem1つのプロパティ(Text別のプロパティ)です。

UpdateSourceTrigger="PropertyChanged"バインディングに追加して、更新をより頻繁に実行します。イベントは必要ありません。

于 2012-09-29T01:45:00.747 に答える
0

さて、私はデータバインディングを完全に取り除き、非常にwinformsスタイルのイベントモデルを使用してデータを更新することになりました。私はまだデータバインディングが機能しない理由を理解できません。誰かがデータバインディングを使用する解決策を持っているなら、私はそれを答えとして受け入れます。

于 2012-10-03T13:31:34.760 に答える
0

コンバーターは新しいオブジェクトを作成しますが、ItemTemplateのTextBlock内のテキストは元のオブジェクトにバインドされたままです。したがって、新しいオブジェクトのNameプロパティを変更しても、明らかに変更されません。

于 2012-09-29T09:51:04.627 に答える