动态创建的按钮;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;
                    }
                }
            }

谢谢你,并致以最良好的问候!!!

动态创建的按钮;t使用WPF MVVM XAML更新正在更改的DataSource

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));
        }
    }
}