我有一个带有usercontrol的主窗口。在usercontrol的默认构造函数中添加代码时,设计器停止显示主窗口。它给出了一个信息:
加载问题
该文档包含在加载设计器之前必须修复的错误 修复错误后重新加载设计器。
重新加载设计师
为什么会这样?
这是我在构造函数中的代码:
using (var context = new Data.TVShowDataContext())
{
var list = from show in context.Shows
select show;
listShow.ItemsSource = list;
}
如果我不能使用构造函数来填充gui数据,我应该在什么时候进行呢?用绑定做这个会更好吗?任何吸烟怎么样?
答案 0 :(得分:13)
WPF设计器将在显示子元素时对子元素执行构造函数。我的猜测是你在构造函数中有代码在设计时抛出异常,可能是因为它使用的是一个仅在运行时可用的对象。一个解决方案是用一个检查来包围你的构造函数逻辑,以防止它在设计器中显示时执行。
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
using (var context = new Data.TVShowDataContext())
{
var list = from show in context.Shows
select show;
listShow.ItemsSource = list;
}
}
答案 1 :(得分:1)
我个人会为我的数据源使用一个可观察的集合。有很多例子,但基本上你的代码看起来像这样。我还没有测试过这段代码。如果您有任何问题,请添加一些评论。
这里有两个要点。一,除非你没有处于设计模式,否则不要加载任何数据,(如果你需要设计支持,你可以把if和else语句加载存根POCO数据)。第二,你应该在一个单独的线程上加载你的数据然后你的UI线程。
代码有几处更新。我将(新线程)更改为使用QueueUserWorkItem,我更改了AddItems方法,因为ObservableCollection不支持AddRange,我更改了IEnumerable上的拼写
public class TvShowsDataSource
{
public ObservableCollection<Show> Shows { get; set; }
private void AddItems(IEnumerable<Show> shows)
{
foreach(var show in shows)
Shows.Add(show);
}
public void LoadShowsAsync(Dispatcher dispatcher)
{
ThreadPool.QueueUserWorkItem((state) =>
LoadShows(dispatcher));
}
private void LoadShows(Dispatcher dispatcher)
{
if (dispatcher == null)
throw new ArgumentNullException("dispatcher");
using (var context = new Data.TVShowDataContext())
{
var list = from show in context.Shows
select show;
dispatcher.Invoke(AddItems(list));
}
}
}
public class UserControl1
{
private readonly TvShowsDataSource tvShowsDataSource;
public UserControl1() : this(new TvShowsDataSource()) {}
public UserControl1(TvShowsDataSource tvShowsDataSource )
{
InitializeComponent();
this.tvShowsDataSource = tvShowsDataSource;
listShow.ItemsSource = tvShowsDataSource.Shows;
this.Loaded += UserControl1_Loaded;
}
public void UserControl1_Loaded(object sender, RoutedEventArgs e)
{
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
tvShowsDataSource.LoadShowsAsync(this.Dispatcher);
}
}
}