2014-10-02 18 views
0

我是MVVM和XAML的新手,我碰到了一個障礙。任何幫助你可以給予不勝感激!我們使用WPF/MVVM和XAML在WrapPanel上動態創建按鈕。按鈕顯示爲正常,並綁定到可觀察集合(RigDataSrceClass)。 (可觀察的集合通過調用SQL存儲的Proc來提供,然後通過訂閱到Pub/Sub來使用新的按鈕狀態(背景和前景色)更新。)動態創建按鈕不會更新使用WPF MVVM更改的數據源XAML

數據正確地進入集合,但是按鈕背景/前景不更新 - 他們永遠保持原來的顏色。隨着狀態在RigDataSrceClass中更改,我需要使用新狀態值更新所有按鈕。

我試過8種不同的方式來更新按鈕顏色,包括鼠標懸停事件上的樣式模板(它只改變字體/前景色,並且不會從數據源獲取更新),cs代碼隱藏構建和更新按鈕(這在非MVVM中工作,但在MVVM中,RigDataSrceClass在視圖中不可用)以及模板和控件的無限量綁定,所有這些都沒有任何效果。加上這些沒有工作:

private void dispatcherTimer_Tick(object sender, EventArgs e) 
    { 
     this.Content = new ContentControl(); //Wipes out my buttons!    

     RigButtonsClassControl.InvalidateArrange(); // No effect 

     this.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate); // No effect 

     CommandManager.InvalidateRequerySuggested(); // No effect 

    } 

的XAML如下:

<Grid> 
    <ItemsControl x:Name="RigButtonsClassControl" ItemsSource="{Binding RigDataSrceClass,  Mode=OneWay}" Grid.Row="1" > 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <WrapPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Top"/> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 

<Button Tag="{Binding Id}" x:Name="RigBtn" Content="{Binding RigContent, Mode=TwoWay}" Style="{StaticResource myStyle}" Click="Button_RefreshControl_Click" FontWeight="Bold" Width="33" MaxHeight="33" Margin="1" Background="{Binding RigStatus}" Foreground="{Binding RigStatusForeground}" /> 

       </DataTemplate> 
     </ItemsControl.ItemTemplate>   
    </ItemsControl>    
</Grid> 

視圖模型CS代碼如下:

public class RigsViewModel : ViewModelBase<IMainView>, IPublishing 
{ 
    ISubscription _subscriptionProxy; 
    string _endpoint = string.Empty; 
    List<String> rigSubscribedList = new List<String>(); 
    String txtTopicName; 

    private ObservableCollection<RigButtonDataModelClass> _ObservCollRigData = new ObservableCollection<RigButtonDataModelClass>(); 
    public ObservableCollection<RigButtonDataModelClass> RigDataSrceClass 
    { 
     get { return _ObservCollRigData; } 
    } 
… 
} 

    public RigsViewModel() 
     : base(new RigsWindow()) 
    { 
     this.ws_context = new FlexViewWCF.EntitiesModelServiceClient(); 
     this.rigFilter = string.Empty; 
     this.isFilteringActive = false; 
     this.Status = string.Empty; 

     _endpoint = ConfigurationManager.AppSettings["EndpointAddress"]; 
     MakeProxy(_endpoint, this); 
     txtTopicName = "R464RigStatus,R469RigStatus,R472RigStatus,R496RigStatus,R498RigStatus,R514RigStatus"; 
     OnSubscribe(); 
     this.RetrieveRigsToDisplay(); 

//   var vm = DataContext as ViewModel; 
//   vm.Resources.Add(new Resource { Id = 1, Content = "Resource 1" }); 

     foreach (FlexViewWCF.CurrentRigCustomerDto dto in this.RigsToDisplay) 
     { 
      RigButtonDataModelClass rbdmc = new RigButtonDataModelClass(); 
      rbdmc.RigContent = dto.RigNumber; 
      rbdmc.RigCommand = null; 
      rbdmc.RigStatusForeground = "Black"; 
      rbdmc.RigStatus = "LightGray"; //dto.Status; 
      RigDataSrceClass.Add(rbdmc); 
     } 
     //this.RigButtonsToDisplay = rigsToDisplay. 
     //RigButtonsToDisplay = 
     //MakeRigButtons(); 
    } 

我更新從這裏認購數據:RigStatus是新的背景顏色和明確定義的前景...

  lock (rigsToDisplay) 
      { 
       foreach (FlexViewWCF.CurrentRigCustomerDto cusRig in rigsToDisplay) 
       { 
        if (cusRig.RigNumber == topicName.Substring(1, 3)) 
        { 
         cusRig.Status = e.EventData.ToString(); 
         break; 
        } 
       } 
       foreach (FlexView.ViewModels.RigButtonDataModelClass cusRig in RigDataSrceClass) 
       { 
        if (cusRig.RigContent == topicName.Substring(1, 3)) 
        { 
         if (e.EventData.ToString() == "Black") 
          cusRig.RigStatusForeground = "White"; 
         else 
          cusRig.RigStatusForeground = "Black"; 
         cusRig.RigStatus = e.EventData.ToString(); 
         break; 
        } 
       } 
      } 

謝謝,最好的問候!

+0

不'RigButtonDataModelClass'執行'INotifyPropertyChanged'? – 2014-10-02 19:39:57

+0

不,不。謝謝。我會嘗試的。 – 2014-10-02 19:52:45

+0

這就是解決方案!如果您將它作爲答案發布,我會接受它。非常感謝你! – 2014-10-02 20:53:17

回答

1

是否RigButtonDataModelClass實施INotifyPropertyChanged

如果不是,您需要將其添加到您的班級並在所需屬性上調用NotifiyPropertyuChanged,這將通知Xaml綁定值已更改並將更新。

簡單的例子:

public class RigButtonDataModelClass : INotifyPropertyChanged 
{ 
    private int _myProperty; 
    public int MyProperty 
    { 
     get { return _myProperty; } 
     set { _myProperty = value; NotifyPropertyChanged(); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    public void NotifyPropertyChanged([CallerMemberName]string propertyname = null) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyname)); 
     } 
    } 
}