【发布时间】:2018-04-16 14:38:58
【问题描述】:
我已将控件绑定到“描述”进度的类类型的某些属性。
一切似乎都很好:
- NotifyPropertyChanged 似乎有效:它会在属性更改时引发(在更新 ProgressViewModel 类实例的属性的情况下)
- 查看 xaml 代码时,当代码运行时,在绑定属性下会显示正确的值(例如:进度等于 0.1)。
问题是视觉上没有任何变化。所以:控件没有更新。全部。
XAML:
<DockPanel LastChildFill="False">
<DockPanel LastChildFill="False">
<StackPanel x:Name="ProgressPart"
DockPanel.Dock="Top"
Visibility="{Binding Visible, Converter={StaticResource ValueConverterBoolToVisibility}}">
<ProgressBar Value="{Binding Path=Progress, Mode=OneWay, Converter={StaticResource ValueConverterTest}}" />
<StackPanel Orientation="Horizontal">
<TextBlock>
<Run Text="Action:" />
<Run Text="{Binding Path=ActionName, Mode=OneWay}" />
</TextBlock>
</StackPanel>
<TextBlock Text="{Binding Path=ActionProgress, Mode=OneWay }" />
</StackPanel>
<StackPanel x:Name="MasterOKPart"
DockPanel.Dock="Top">
</StackPanel>
<StackPanel x:Name="MasterNotOKPart"
DockPanel.Dock="Top">
</StackPanel>
<StackPanel x:Name="FooterPart"
DockPanel.Dock="Bottom">
</StackPanel>
</DockPanel>
</DockPanel>
</UserControl>
后面的控制代码:
public partial class ContentAnomalies : UserControl, INotifyPropertyChanged, IViewControl
{
private ProgressViewModel _ProgressViewModel;
public ProgressViewModel ProgressViewModel
{
get
{
return _ProgressViewModel;
}
set
{
_ProgressViewModel = value;
NotifyPropertyChanged();
}
}
private bool _Prepared;
public bool Prepared
{
get
{
return _Prepared;
}
set
{
if (value == false)
{
_Prepared = value;
return;
}
if (_Prepared==false)
{
ProgressViewModel = new ProgressViewModel
{
Visible = true,
Token = new CancellationTokenSource()
};
Thread myNewThread = new Thread(() => Auditor.AuditContentMD(Globals.ThisAddIn.Application.ActivePresentation, this, ProgressViewModel));
myNewThread.Start();
//ProgressViewModel.Visible = false;
}
}
}
public ContentAnomalies()
{
InitializeComponent();
//ProgressViewModel = new ProgressViewModel();
//ProgressViewModel.Visible = true;
this.ProgressPart.DataContext = ProgressViewModel;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void Prepare()
{
throw new NotImplementedException();
}
}
修改progressViewModel的方法:
internal static void AuditContentMD(PPT.Presentation pres, ContentAnomalies control, ProgressViewModel progressViewModel) { 列出 contentAudits = ReturnContentAudits();
progressViewModel.Visible = true;
progressViewModel.Progress = 0;
progressViewModel.ActionName = "Loading presentation objects...";
List<Anomaly> anomalies = new List<Anomaly>();
Audit audit;
AuditsSupport.SpacesPositions = null;
DateTime timeStart = DateTime.Now;
AuditsSupport.Shapes = SupportVSTO.ReturnAllShapesFromPresentation(Globals.ThisAddIn.Application.ActivePresentation, progressViewModel, 0, (double)1 / (contentAudits.Count + 1));
TimeSpan timeShapes = DateTime.Now - timeStart;
for (int i = 0; i < contentAudits.Count; i++)
{
DateTime timeStartInternal = DateTime.Now;
if (progressViewModel.Token.IsCancellationRequested)
{
return;
}
else
{
audit = contentAudits[i];
progressViewModel.ActionName = audit.Name;
anomalies.AddRange(contentAudits[i].PerformAudit(pres, (double)(i + 1) / (contentAudits.Count + 1), (double)1 / (contentAudits.Count + 1), progressViewModel));
}
progressViewModel.Progress = (double)(i + 2) / (contentAudits.Count + 1);
}
TimeSpan timeWhole = DateTime.Now - timeStart;
MessageBox.Show("all:" + " " + timeWhole.TotalSeconds);
//control.ShowProgressBar(false);
//control.AddAuditsListControlToPanel(anomalies, pres);
}
还有 PogressViewModelClass:
public class ProgressViewModel: INotifyPropertyChanged
{
private double _Progress;
public double Progress
{
get
{
return _Progress;
}
set
{
_Progress = value;
NotifyPropertyChanged();
}
}
private string _ActionName;
public string ActionName
{
get
{
return _ActionName;
}
set
{
_ActionName = value;
NotifyPropertyChanged();
}
}
private string _ActionProgress;
public string ActionProgress
{
get
{
return _ActionProgress;
}
set
{
_ActionProgress = value;
NotifyPropertyChanged();
}
}
private bool _Visible;
public bool Visible
{
get
{
return _Visible;
}
set
{
_Visible = true;
NotifyPropertyChanged();
}
}
private CancellationTokenSource _Token;
public CancellationTokenSource Token
{
get
{
return _Token;
}
set
{
_Token = value;
NotifyPropertyChanged();
}
}
public ProgressViewModel()
{
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
你知道如何解决它吗?
【问题讨论】:
-
所有控件都没有更新。
-
你在哪里设置你的
DataContext? -
如果我没看错,您调用的方法会在不同的线程中更改您的属性,您是否尝试过调用 Dispatcher 中的更改?
-
设置
this.ProgressPart.DataContext = ProgressViewModel时,ProgressViewModel 属性必须先初始化。如果您稍后分配一个值,DataContext 不会神奇地更新,而是保持为空。但是,您可以将 DataContext 属性绑定到 ProgressViewModel 属性。 -
Decoder94:在 ContentAnomalies 构造函数中
标签: c# wpf data-binding