1

セットアップ

したがってComputerItem、特定のコンピューターについて知っておく必要のあるすべてのものを格納するように設計されたクラスがあります。これらのアイテムはに保存されますObservableCollection<ComputerItem>。次に、カスタムコントロールComputerControlがあります。これには、(とりわけ)ComputerItemのメンバーにバインドされたいくつかのテキストボックスがあり、バインドは次のように使用可能になります。

<TextBlock Name="tb_computerName"TextWrapping="Wrap" Text="{Binding ElementName=ComputerControl1, Path=computerName}"/>

と背後のコードで

public static DependencyProperty computerNameProperty = DependencyProperty.Register("computerName", typeof(string), typeof(ComputerControl), null);

MultiselectList次に、ComputerControlオブジェクトを作成します。

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <toolkit:MultiselectList x:Name="lb_computers" IsSelectionEnabledChanged="lb_computers_IsSelectionEnabledChanged"> <!--SelectionChanged="lb_computers_SelectionChanged" >-->
        <toolkit:MultiselectList.ItemTemplate>
            <DataTemplate>
               <StackPanel x:Name="sp">
                    <local:ComputerControl computerName="{Binding Name}" MACAddress="{Binding DisplayMAC}" playClicked="playClicked_Handler" editClicked="editClicked_Handler"/>
                </StackPanel>
            </DataTemplate>
        </toolkit:MultiselectList.ItemTemplate>
    </toolkit:MultiselectList>
</Grid>

ComputerControl定義でデータバインディングを確認できます。背後にあるコードで、ObservableCollectionをMultiselectListにバインドします。

this.lb_computers.ItemsSource = ComputerListMaintainer.GetList();

そして、これらすべて(およびここに含めるのを忘れていると確信しているいくつかのこと)は、ObservableCollection内のComputerItemsを表すComputerControlsでMultiselectListを埋めるために美しく機能します。

問題

私の問題は、基になるComputerItemが変更されたときに、対応するComputerControlのTextBlockが更新されないことです。INotifyPropertyChangedComputerItemクラスに実装しました:

public class ComputerItem : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private string name;

    protected virtual void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    public string Name
    {
        get { return name; }
        set { OnPropertyChanged("Name"); name = value; }
    }
}

しかし、それは問題を解決しませんでした。ComputerControlと関係があるのではないかと思いますが、どこから探し始めればよいのかわかりません。私が見つけた最も近い質問は、INotifyPropertyChangedが解決策であるべきだと示唆しましたが、私が正しく覚えていれば、彼らはその場合はカスタムコントロールを使用せず、カスタムクラスのみを使用していました。

私は何が欠けていますか?

4

1 に答える 1

2

さて、あなたのセッターは初心者には正しくありません。また、この種の配管作業に優れたAPIを提供するMvvmLightも調べてください。

public string Name
{
    get { return name; }
    set 
    { 
        if(value != name)
        {
            name = value;
            OnPropertyChanged("Name"); 
        }
    }
}

アップデート:

コードビハインドでlb_computers.ItemsSourceを設定しないでください。これは、1回限りの操作であり、バインディングではないためです。監視可能なオブジェクトのObservableCollection(別名INotifyPropertyChanged)にバインドすることをお勧めします。

また、依存関係プロパティを適切に宣言しているかどうかもわかりません。そのため、以下に「バインド可能な」プロパティを定義する方法に関する適切な設定を示します。

また、XAMLでは、コードのアーキテクチャが重要であり、適切なエクスペリエンスを提供します。Mvvmパターンを利用することを強くお勧めします。MvvmLightとMEFedMVVMは、私の開発に非常に役立ちます。これには最初は少し作業が必要ですが、将来の問題をデバッグしてコードを保守する方がはるかに簡単です。

これらのヒントが役に立たない場合は、完全なコードを確認する必要があります。

バインド可能なプロパティの宣言

#region ReportName

    public string ReportName
    {
        get { return (string)GetValue(ReportNameProperty); }
        set { SetValue(ReportNameProperty, value); }
    }

    public static readonly DependencyProperty ReportNameProperty = DependencyProperty.Register("ReportName",
        typeof(string), typeof(ExportableGridView), new PropertyMetadata("Report", new PropertyChangedCallback(OnReportNameChanged)));

    public static void OnReportNameChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ExportableGridView control = sender as ExportableGridView;
        control.titleTextBlock.Text = e.NewValue as string;
    }

#endregion ReportName
于 2012-04-18T16:12:10.933 に答える