如何使用 MVVM 同时绑定 Progressbar 和 Datagrid? [英] How to bind Progressbar and Datagrid at the same time using MVVM?
问题描述
我正在尝试使用 MVVM 构建进度条.基本上,我有一个主要的 xaml 和 2 个用户控件,1 个用于数据网格的进度条 1.我有点新,我关注了这个问答,但我没有得到任何成功.下面是我的 ViewModel 代码和 Xaml 代码.基本上我有两个问题,
I am trying to build a progressbar using MVVM. Basically, I have a main xaml and 2 UserControls, 1 for progressbar 1 for datagrid. I am bit new and I followed this question and answer but I havent got any success. Below is my ViewModel code and Xaml code. Basically I have 2 problems,
1-如何绑定 CustomerModels 或者甚至可能的话 CustomerViewModel?我尝试将 Itemsource 绑定直接与 ObservableCollection 一起使用,我正在用我的 delegateCommand 填充它,该委托命令与后台工作人员一起运行,但没有成功.我试过没有委托和后台工作人员,简单地使用如下.
1-How to bind CustomerModels or if even possible CustomerViewModel? I tried to use Itemsource binding direcly with ObservableCollection which I am filling with my delegateCommand that runs with a backgroundworker but no success. I tried without delegate and backgroundworker,simply using as below.
Me.myLoadCommand = New Commands.LoadCustomerModels()
Me.myLoadCommand = New Commands.LoadCustomerModels()
我做错了什么?
<UserControl.Resources>
<vm:CustomerModelsVM x:Key="Customerobj"></vm:CustomerModelsVM>
</UserControl.Resources>
<Grid >
<DataGrid x:Name="grdData" ItemsSource="{Binding Path=CustomerModels}"/>
</Grid>
2-如何绑定CurrentProgressBar?我试图以同样的方式绑定进度条状态,但我相信我的 ViewModel 和 Xaml 不知何故没有联系.
2-How to bind CurrentProgressBar? I tried to bind the progress bar status same way but I believe my ViewModel and Xaml somehow has no connection.
<UserControl x:Class="ucProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
>
<Grid>
<ProgressBar Value="{Binding CurrentProgress, Mode=OneWay}" Visibility="{Binding ProgressVisibility}"></ProgressBar>
<TextBlock Text="{Binding ElementName=myProgressBar, Path=Value, StringFormat={}{0:0}%}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>
命名空间视图模型
Public Class CustomerModelsVM
Implements ICustomerModelsVM
Implements INotifyPropertyChanged
Public Event PropertyChanged As PropertyChangedEventHandler _
Implements INotifyPropertyChanged.PropertyChanged
Private ReadOnly worker As BackgroundWorker
Private m_currentProgress As Integer
Private _CustomerModels As New ObservableCollection(Of Models.CustomerModel)
Private mySaveCommand As ICommand
Private myLoadCommand As ICommand
Public Sub New()
Me.worker = New BackgroundWorker()
Me.myLoadCommand = New DelegateCommand(Sub() Me.worker.RunWorkerAsync(), AddressOf Progressisbusy)
' _CustomerModels = getCustomerModels()
Me.worker = New BackgroundWorker()
AddHandler Me.worker.DoWork, AddressOf Me.DoWork
AddHandler Me.worker.ProgressChanged, AddressOf Me.ProgressChanged
End Sub
Private Sub ProgressChanged(sender As Object, e As ProgressChangedEventArgs)
Me.CurrentProgress = e.ProgressPercentage
End Sub
Private Function Progressisbusy() As Boolean
Return Not Me.worker.IsBusy
End Function
Private Sub OnPropertyChanged(Optional ByVal propertyName As String = Nothing)
RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
End Sub
Public ReadOnly Property CustomerModels() As ObservableCollection(Of Models.CustomerModel)
Get
Return _CustomerModels
End Get
End Property
Public ReadOnly Property btnClick() As ICommand
Get
Return myLoadCommand
End Get
End Property
Public Property CurrentProgress() As Integer
Get
Return Me.m_currentProgress
End Get
Private Set(value As Integer)
If Me.m_currentProgress <> value Then
Me.m_currentProgress = value
OnPropertyChanged(Me.CurrentProgress)
End If
End Set
End Property
Private Sub DoWork(sender As Object, e As DoWorkEventArgs)
_CustomerModels = getCustomerModels()
End Sub
Function getCustomerModels() As ObservableCollection(Of Models.CustomerModel) Implements ICustomerModelsVM.GetCustomerModels
If _CustomerModels Is Nothing OrElse _CustomerModels.Count = 0 Then myLoadCommand.Execute(_CustomerModels)
Return _CustomerModels
End Function
推荐答案
我想用一个可行的解决方案来回答我的问题.就我而言,问题很简单,我必须使用调度程序来清除我的可观察集合.所以我的 Do_work 函数如下所示.在开始绑定之前,我没有清除可观察集合.添加这个简单的行使我的代码工作.
I would like answer my question with a working solution. In my case problem was simply, I had to use dispatcher to clear my oberservable collection. So my Do_work function looks like as following. I didnt clear the observable collection before I start binding. Adding this simple line makes my code working.
Private Sub DoWork(sender As Object, e As DoWorkEventArgs)
Application.Current.Dispatcher.BeginInvoke(Sub() Me.CustomerModels.Clear())
' Me.CustomerModels.Clear()
For index = 1 To 100
Dim CustomerModel As New CustomerModel With { _
.age = 30 + index, _
.name = "testName" & index, _
.surname = "testSurname" & index, _
.Id = index}
Application.Current.Dispatcher.BeginInvoke(Sub() CustomerModels.Add(CustomerModel))
' CustomerModels.Add(CustomerModel)
Thread.Sleep(100)
worker.ReportProgress(CalculateProgress(100, index))
Next
End Sub
这篇关于如何使用 MVVM 同时绑定 Progressbar 和 Datagrid?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!