5

たとえば、次のタイプがあるとします。

    public class Site
    {
       public string Name { get; set; }
       public int SiteId { get; set; }
       public bool IsLocal { get; set; }
    }

上記の型は、ViewModel のプロパティに保持されるように割り当てることができるため、対応するバッキング フィールドが作成されているが、ここでは省略されていると仮定します。

    public Site SelectedSite
    {
        get { return _selectedSite; }
        set
        {
            _selectedSite = value;
            // raise property changed etc
        }
    }

私のxamlでは、単純なバインディングは次のようになります:

            <TextBlock x:Name="StatusMessageTextBlock"
                   Width="Auto"
                   Height="Auto"
                   Style="{StaticResource StatusMessageboxTextStyle}"
                   Text="{Binding MessageToDisplay,
                                  Mode=OneWay,
                                  UpdateSourceTrigger=PropertyChanged}" />

ドット表記構文を使用してバインドを拡張できますか? 例えば:

            <TextBlock x:Name="StatusMessageTextBlock"
                   Width="Auto"
                   Height="Auto"
                   Style="{StaticResource StatusMessageboxTextStyle}"
                   **Text="{Binding SelectedSite.Name,**
                                  Mode=OneWay,
                                  UpdateSourceTrigger=PropertyChanged}" />

興味深い機能のように思えますが、DC が RunTime で割り当てられているため、DesignTime または CompileTime でこの機能が機能するかどうかの手がかりが見えないので、私の直感はノーです。

複雑なオブジェクトとは何かを誤解している場合は訂正してください。この質問のために単純化しました。

4

2 に答える 2

6

もちろん、これは可能です。ただし、WPF は、パスに沿ったプロパティがいつ変更されたかを知る必要があります。そのためには、実装INotifyPropertyChanged(またはサポートされている他のメカニズム) が必要です。あなたの例では、両方Siteを含む VM がSelectedSite変更通知を実装する必要があります)。

質問で指定した機能を実装する方法は次のとおりです。

// simple DTO
public class Site
{
   public string Name { get; set; }
   public int SiteId { get; set; }
   public bool IsLocal { get; set; }
}

// base class for view models
public abstract class ViewModel
{
    // see http://kentb.blogspot.co.uk/2009/04/mvvm-infrastructure-viewmodel.html for an example
}

public class SiteViewModel : ViewModel
{
    private readonly Site site;

    public SiteViewModel(Site site)
    {
        this.site = site;
    }

    // this is what your view binds to
    public string Name
    {
        get { return this.site.Name; }
        set
        {
            if (this.site.Name != value)
            {
                this.site.Name = value;
                this.OnPropertyChanged(() => this.Name);
            }
        }
    }

    // other properties
}

public class SitesViewModel : ViewModel
{
    private readonly ICollection<SiteViewModel> sites;
    private SiteViewModel selectedSite;

    public SitesViewModel()
    {
        this.sites = ...;
    }

    public ICollection<SiteViewModel> Sites
    {
        get { return this.sites; }
    }

    public SiteViewModel SelectedSite
    {
        get { return this.selectedSite; }
        set
        {
            if (this.selectedSite != value)
            {
                this.selectedSite = value;
                this.OnPropertyChanged(() => this.SelectedSite);
            }
        }
    }
}

ビューは次のようになります ( aDataContextが type であると仮定SitesViewModel):

<ListBox ItemsSource="{Binding Sites}" SelectedItem="{Binding SelectedSite}"/>
于 2012-04-19T15:48:52.630 に答える
0

以下は私のために働いたものです:

        public Site SelectedSite
        {
            get { return _selectedSite; }
            set
            {
                _selectedSite = value;
                RaisePropertyChanged("SelectedSite");
            }
        }

私のxamlでは、次のことができました:

        <TextBox Name="tbSiteName"
                 Width="250"
                 Height="30"
                 Margin="0"
                 HorizontalAlignment="Left"
                 VerticalAlignment="Top"
                 IsReadOnly="True"
                 Style="{StaticResource MainTextBoxStyle}"
                 Text="{Binding SelectedSite.Name,
                          Mode=OneWay,
                          UpdateSourceTrigger=PropertyChanged}" />

これにより、サイト タイプの各データ メンバーをラップする個別のプロパティを作成しなくても、サイト タイプのデータ メンバーにアクセスできます。次に、個々のコントロールを VM で宣言された各プロパティにバインドできます。1 対 1 の方法では、このアプローチはかなり冗長になる可能性があります。上記の TextBox コントロールの Text プロパティに添付されたバインディング拡張は、単純な単純なプロパティではなく、実際にはカスタム タイプにバインドしていることを示しています。より多くのパブリック プロパティを作成する必要がなくなる可能性があります。

于 2012-04-20T09:51:52.743 に答える