动态创建的按钮;t使用WPF MVVM XAML更新正在更改的DataSource
本文关键字:更新 DataSource XAML WPF 按钮 创建 动态 使用 MVVM | 更新日期: 2023-09-27 18:25:26
我是MVVM和XAML的新手,遇到了一个路障。非常感谢您能提供的任何帮助!我们使用WPF/MVVM和XAML在WrapPanel上动态创建按钮。按钮显示为正常,并绑定到一个可观察的集合(RigDataSerceClass)。(可观察的集合通过调用SQL存储的Proc来提供,然后通过订阅Pub/Sub来更新为新的按钮状态(背景和前景颜色)。)
数据正确进入集合,但按钮背景/前景不会更新——它们永远保持原始颜色。我需要所有的按钮更新为新的状态值,因为状态在RigDataSerceClass中发生了更改。
我已经尝试了大约8种不同的方法来更新按钮颜色,包括鼠标悬停事件上的样式模板(它只更改字体/前景颜色,不从数据源进行更新),构建和更新按钮的cs代码(这在非MVVM中有效,但在MVVM中RigDatarceClass在视图中不可用),以及无休止的模板和控件绑定,所有这些都没有任何效果。此外,这些都不起作用:
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>
View Model 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
吗?
如果没有,则需要将其添加到类中,并对所需的属性调用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));
}
}
}