2017-04-05 64 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总是扩展。 一如既往,我坚持专注于复杂的东西,而解决方案很简单。