强制数据绑定初始化

时间:2010-08-19 13:06:23

标签: wpf data-binding media-player

有没有办法可以强制数据绑定在创建后立即在控件上初始化?

我的问题是我已经创建了一个自己的UserControl派生控件,它必须在显示之前进行一些耗时的处理。更准确地说,使用.Net的MediaPlayer组件创建视频媒体的缩略图。我在自定义的MenuItem控件中显示我的控件。

现在正常工作,控件在显示之前就会被初始化(当选择父MenuItem时),这会启动耗时的工作并迫使我显示某种“处理项目”信息,直到控件完成工作。

我需要找到一种方法,在显示主窗口之前立即执行文件名的数据绑定,而不是在显示控件之前执行。有可能吗?

我创建了一个小应用来证明我的问题:

Window1.xaml

<Window x:Class="TestBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

  <Window.Resources>
    <Style x:Key="MyMenuStyle" TargetType="MenuItem">
      <Setter Property="Header" Value="{Binding MenuHeader}"/>
    </Style>
  </Window.Resources>

  <Grid>
    <Menu>
      <MenuItem Header="Data">
        <MenuItem Header="Submenus" ItemsSource="{Binding SubMenus}" ItemContainerStyle="{StaticResource MyMenuStyle}" />
      </MenuItem>
    </Menu>
  </Grid>
</Window>

Window1.xaml.cs

using System.Collections.ObjectModel;
using System.Windows;

namespace TestBinding
{
  public partial class Window1 : Window
  {
    public Window1()
    {
       InitializeComponent();
       DataContext = new BindingViewModel();
    }
  }

  class BindingViewModel
  {
    public ObservableCollection<MyMenuItems> SubMenus { get; set; }

    public BindingViewModel()
    {
      SubMenus = new ObservableCollection<MyMenuItems>();
      SubMenus.Add(new MyMenuItems("Menu 1"));
      SubMenus.Add(new MyMenuItems("Menu 2"));
      SubMenus.Add(new MyMenuItems("Menu 3"));
    }
  }

  public class MyMenuItems
  {
    private string _menuHeader;
    public string MenuHeader
    {
      get
      {
        return _menuHeader;
      }
      set
      {
        _menuHeader = value;
      }
    }

    public MyMenuItems(string header)
    {
      _menuHeader = header;
    }
  }
}

如果您运行此程序并在该行上设置断点 return _menuHeader; 您会注意到,这会在您选择父菜单项时执行。 我希望程序在显示主窗口后尽快完成子菜单项的绑定,为程序提供一些时间来处理绑定属性给出的值。

2 个答案:

答案 0 :(得分:2)

您是否尝试过PriorityBinding

<PriorityBinding>
    <Binding Path="SlowestProperty" IsAsync="True" />
    <Binding Path="MediumSpeedProperty" IsAsync="True" />
    <Binding Path="FastestProperty" />
</PriorityBinding>

绑定是从上到下处理的,所以一定要设置IsAsync属性(以异步方式运行) - 否则,它将挂起第一个直到完成,然后挂在第二个,最后是第三个一,冻结过程中的UI。将绑定放入最慢到最快的顺序(从上到下)以按顺序启动它们。

当返回值时,更高优先级的值会替换较低优先级的值(但不是相反,如果“最慢”的值首先返回)。

答案 1 :(得分:0)

所以我理解的问题是(在你的例子中),MenuHeader get属性必须计算需要几秒钟的东西,然后在完成计算后返回?

如果是这种情况,你可以做的是在MyMenuItems的构造函数中进行复杂的计算,并只缓存最终读取MenuHeader属性的值。这可能会在启动时挂起你的程序,因此你应该在构造函数中生成一个新线程来加载缓存的属性值。