我是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;
}
}
}
謝謝,最好的問候!
不'RigButtonDataModelClass'執行'INotifyPropertyChanged'? – 2014-10-02 19:39:57
不,不。謝謝。我會嘗試的。 – 2014-10-02 19:52:45
這就是解決方案!如果您將它作爲答案發布,我會接受它。非常感謝你! – 2014-10-02 20:53:17