Принудительно инициализировать привязку данных - PullRequest
1 голос
/ 19 августа 2010

Есть ли способ принудительно инициализировать привязки данных в элементах управления сразу после их создания?

Моя проблема в том, что я создал собственный производный элемент управления UserControl, который должен выполнять некоторую трудоемкую обработку доэто показано.Точнее, создавайте миниатюры видео-медиа, используя компонент MediaPlayer .Net.Я отображаю свой элемент управления в пользовательском элементе управления 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 ]

2 голосов
/ 19 августа 2010

Вы пробовали PriorityBinding ?

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

Привязки обрабатываются сверху вниз, поэтому обязательно установите свойство IsAsync (чтобы запускать их асинхронно) - в противном случае оно просто будет зависать на первом до полного, затем на втором и, наконец, на третьем один, замораживая пользовательский интерфейс в процессе. Поместите привязки в порядке от медленного до самого быстрого (сверху вниз), чтобы начать их в этом порядке.

Когда возвращаются значения, значения с более высоким приоритетом заменяют значения с более низким приоритетом (но не наоборот, если сначала возвращается «самый медленный»).

0 голосов
/ 09 сентября 2010

Итак, в чем я понимаю проблему, так как (в вашем примере) свойство get MenuHeader должно вычислить что-то, что займет несколько секунд, а затем вернется после завершения вычисления?

Если это так, то вы могли бы выполнить сложные вычисления в конструкторе MyMenuItems и просто кэшировать значение, когда свойство MenuHeader наконец-то будет прочитано. Это, вероятно, приведет к зависанию вашей программы при запуске, и поэтому вам следует в конструкторе создать новый поток для загрузки значения свойства в кэше.

...