2017-04-05 32 views
1

我有一個自定義行爲,它需要一個布爾值作爲參數。我試圖將它綁定到我的模型中的一個屬性,但我無法讓它工作。 (我使用的DevExpress)WPF綁定到行爲屬性不起作用

<dxg:GridControl 
     x:Name="dgArticles" 
     Grid.Row="1" 
     AutoGenerateColumns="None" 
     ItemsSource="{Binding Path=Articles, Mode=TwoWay}"> 

     <dxmvvm:Interaction.Behaviors> 
      <util:ExpandAllBehavior HasLotPartie="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CahierDesCharges.HasLotPartie }" /> 
     </dxmvvm:Interaction.Behaviors> 


    </dxg:GridControl 

這是一個WPF用戶控件和DataContext的是在後臺代碼定義如下:

public partial class GridView : UserControl 
{ 
    public GridView(ArticleViewModel a) 
    { 
     InitializeComponent(); 
     this.DataContext = a;   
    }   
} 

我的視圖模型:

public class ArticleViewModel : INotifyPropertyChanged 
{ 

    private Cahier cahierDesCharges; 
    public Cahier CahierDesCharges { get { return cahierDesCharges; } set { } } 

    private ObservableCollection<Article> articles; 
    public ObservableCollection<Article> Articles 
    { 
     get { return articles; } 
     set { articles = value; OnPropertyChanged("articles"); } 
    } 

    public ArticleViewModel() { } 

    public ArticleViewModel(Cahier c) 
    { 
     this.cahierDesCharges = c; 
     this.articles = CahierDesCharges.Articles; 
    } 

    private void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, 
       new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 

    } 
} 

而CahierDesCharges類別:

public class Cahier : INotifyPropertyChanged 
{ 
    public bool HasLotPartie { get; set; } 

    private ObservableCollection<Article> articles; 
    public ObservableCollection<Article> Articles 
    { 
     get { return articles; } 
     set { articles = value; OnPropertyChanged("articles"); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public Cahier() { } 
    private void OnPropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, 
       new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 
     Console.WriteLine(propertyName); 
    } 
} 

行爲:

public class ExpandAllBehavior : Behavior<GridControl> 
{ 
    public static readonly DependencyProperty HasLotPartieProperty = 
    DependencyProperty.Register("HasLotPartie", typeof(Boolean), typeof(ExpandAllBehavior)); 
    public bool HasLotPartie 
    { 
     get { return (bool)GetValue(HasLotPartieProperty); } 
     set { SetValue(HasLotPartieProperty, value); } 
    } 

    protected override void OnAttached() 
    { 
     if (HasLotPartie) 
     { 
      base.OnAttached(); 

      this.AssociatedObject.CustomRowFilter += AssociatedObject_Loaded; 
     } 

    } 

    void AssociatedObject_Loaded(object sender, EventArgs e) 
    { 
     int dataRowCount = AssociatedObject.VisibleRowCount; 
     for (int rowHandle = 0; rowHandle < dataRowCount; rowHandle++) 
      AssociatedObject.ExpandMasterRow(rowHandle); 


    } 



    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
    } 
} 

我在不同的地方使用了行"{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CahierDesCharges.HasLotPartie }",我知道它的工作。在下面的例子中它的工作完美的罰款:

<dxg:GridControl.View> 
      <dxg:TableView 
       AllowScrollAnimation="True" 
       EnableImmediatePosting="True" 
       IsDetailButtonVisibleBinding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.CahierDesCharges.HasLotPartie }" 
       Name="view" 
       ShowGroupedColumns="False" 
       ShowGroupPanel="False" 
       UseLightweightTemplates="None" /> 
     </dxg:GridControl.View> 

行爲工作正常,如果我手動設置的值設置爲true:<util:ExpandAllBehavior HasLotPartie="True" />所以我想,這可能是該DadaContext不繼承我用的伎倆解釋托馬斯·萊維斯克在他的博客here這是我得到了什麼:

<dxg:GridControl.Resources>    
      <util:BindingProxy x:Key="proxy" Data="{Binding}" /> 
     </dxg:GridControl.Resources> 
     <dxmvvm:Interaction.Behaviors> 
      <util:ExpandAllBehavior HasLotPartie="{Binding Data.CahierDesCharges.HasLotPartie, Source={StaticResource proxy}}" /> 
     </dxmvvm:Interaction.Behaviors> 

我用這一招幾個時間,我知道它的作品太多,但不是在這種情況下。現在,我經過幾個小時的搜索後,堅持這一點,所以任何幫助都非常受歡迎。

謝謝

+0

我不確定,但是'HasLotPartie'總是假的? 我的意思是嘗試在行爲中進行檢查並在AssociatedObject的Loaded上註冊事件。 也許當它在OnAttached中,綁定不解決當前值。 – Mishka

+0

使用BindingProxy應該可以工作。你怎麼知道它沒有? – mm8

+0

@Mishka我已經檢查過調試器,我的模型中的'HasLotPartie'被設置爲true,但綁定不起作用,所以行爲的默認值是布爾值爲false。我試圖在AssociatedObject.Loaded上註冊事件,但沒有運氣。 – Hugo

回答

0

好了,所以我想我的CahierDesCharges是空的行爲被認爲是時候。因此HasLotPartie無論如何都是錯誤的,所以它沒有達到我的事件。所以我只是移動我的if()AssociatedObject_Loaded方法,它的工作。我需要等到GridControl完全加載後,CahierDesCharges纔不再爲空。 這是我現在的行爲類:

public class ExpandAllBehavior : Behavior<GridControl> 
{ 
    public static readonly DependencyProperty HasLotPartieProperty = 
    DependencyProperty.Register("HasLotPartie", typeof(bool), typeof(ExpandAllBehavior)); 

    public bool HasLotPartie 
    { 
     get { return (bool)GetValue(HasLotPartieProperty); } 
     set { SetValue(HasLotPartieProperty, value); } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     this.AssociatedObject.Loaded += AssociatedObject_Loaded; //Apllied after GridControl is fully loaded. 
     this.AssociatedObject.CustomRowFilter += AssociatedObject_Loaded; //Applied after filtering on Rows 
    } 

    void AssociatedObject_Loaded(object sender, EventArgs e) 
    { 
     if (HasLotPartie) 
     { 
      int dataRowCount = AssociatedObject.VisibleRowCount; 
      for (int rowHandle = 0; rowHandle < dataRowCount; rowHandle++) 
       AssociatedObject.ExpandMasterRow(rowHandle); 
     } 
    } 



    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
    } 
} 

現在,當HasLotPartie是真的,是希望達到的效果我MasterDetails總是擴展。 一如既往,我堅持專注於複雜的東西,而解決方案很簡單。