[WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 14.07.10 03:37
Оценка:
Есть коллекция объектов, представляющих собой параметры некоторого контрола, который расположен на вкладках TabControl'а.
В разметке XAML к данной коллекции привязывается ItemsSource TabControl'а через класс, реализующий интерфейс IValueConverter.
Всё работает, но при изменении содержимого коллекции (добавлении нового объекта) не срабатывает привязка.
Как только исключаю из привязки конвертер, сразу ситуация исправляется.
Т.е. при использовании конвертера создаётся коллекция TabItem'ов, и уже к ней привязывается ItemsSource, а не к источнику, указанному в привязке.
Как сделать так, чтобы привязка с использованием конвертера срабатывала при изменении источника, указанного в привязке.
Re: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 14.07.10 04:10
Оценка:
Здравствуйте, dx.dash, Вы писали:

DD>Есть коллекция объектов, представляющих собой параметры некоторого контрола, который расположен на вкладках TabControl'а.

DD>В разметке XAML к данной коллекции привязывается ItemsSource TabControl'а через класс, реализующий интерфейс IValueConverter.
DD>Всё работает, но при изменении содержимого коллекции (добавлении нового объекта) не срабатывает привязка.
DD>Как только исключаю из привязки конвертер, сразу ситуация исправляется.
DD>Т.е. при использовании конвертера создаётся коллекция TabItem'ов, и уже к ней привязывается ItemsSource, а не к источнику, указанному в привязке.
DD>Как сделать так, чтобы привязка с использованием конвертера срабатывала при изменении источника, указанного в привязке.
Слежение за изменением коллекции реализовано на уровне ItemsControl, а не Binding. Т.к. ItemsControl получает значение на выходе из конвертера, то вполне логично, что он не парится по поводу исходной коллекции. Меня вот что беспокоит, для чего здесь вообще конвертер, ведь TabControl сам может формировать TabItem-ы?
Re[2]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 14.07.10 04:28
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Меня вот что беспокоит, для чего здесь вообще конвертер, ведь TabControl сам может формировать TabItem-ы?


Всё верно, но дело в том, что на входе конвертера коллекция типа:
Коллекция<Направление> Направления;
Направление {
  Наименование;
  Коллекция<Станция> Станции;
  ...
}
Станция {
  Наименование;
  Контроллер;
  Коллекция<Состояние> Состояния;
  ...
}
...

, из которой конвертер делает набор панелей определённого вида, которые уже вставляет в коллекцию TabItem'ов
Re[3]: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 14.07.10 06:56
Оценка:
Здравствуйте, dx.dash, Вы писали:

MM>>Меня вот что беспокоит, для чего здесь вообще конвертер, ведь TabControl сам может формировать TabItem-ы?

DD>, из которой конвертер делает набор панелей определённого вида, которые уже вставляет в коллекцию TabItem'ов
А почему нельзя всё это представить через DataTemplate? На каждое направление создается TabItem, в нем TextBlock с наименованием и ItemsControl для перечисления станций...
Re[4]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 14.07.10 08:07
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>А почему нельзя всё это представить через DataTemplate? На каждое направление создается TabItem, в нем TextBlock с наименованием и ItemsControl для перечисления станций...


Потому, что для отображения станций используется контрол, производный от UserControl, и в нём нет свойства ItemsSource. Реализовать его как ItemsControl было бы просто замечательно, но сейчас на это нет ни времени, ни опыта.
Но вообще — да, так изначально и было задумано.
Re[5]: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 14.07.10 10:00
Оценка:
Здравствуйте, dx.dash, Вы писали:

MM>>А почему нельзя всё это представить через DataTemplate? На каждое направление создается TabItem, в нем TextBlock с наименованием и ItemsControl для перечисления станций...


DD>Потому, что для отображения станций используется контрол, производный от UserControl, и в нём нет свойства ItemsSource. Реализовать его как ItemsControl было бы просто замечательно, но сейчас на это нет ни времени, ни опыта.

DD>Но вообще — да, так изначально и было задумано.
Пускай нет. Как-то же ему список станций все-равно подсовывается. Неужто нельзя нечто сделать подобное:
<TabControl>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Наименование}"/>
                <UserControl Станции="{Binding ТамГдеСтанции}"/>
            </StackPanel>
        </DataTemplate>
    </TabControl.ContentTemplate>
</TabControl>
Re[6]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 14.07.10 12:00
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Пускай нет. Как-то же ему список станций все-равно подсовывается. Неужто нельзя нечто сделать подобное:

MM>
<TabControl>
MM>    <TabControl.ContentTemplate>
MM>        <DataTemplate>
MM>            <StackPanel>
MM>                <TextBlock Text="{Binding Наименование}"/>
MM>                <UserControl Станции="{Binding ТамГдеСтанции}"/>
MM>            </StackPanel>
MM>        </DataTemplate>
MM>    </TabControl.ContentTemplate>
MM></TabControl>


<l:SizeableTabControl x:Name="панельНаправлений" TabStripPlacement="Left" Grid.Row="1">
  <l:SizeableTabControl.Размер>
    <Binding Source="{x:Static Application.Current}" Path="Настройки.ШиринаПанелиНаправлений" Mode="TwoWay" />
  </l:SizeableTabControl.Размер>
  <l:SizeableTabControl.ItemsSource>
    <Binding Source="{x:Static Application.Current}" Path="Конфигурация.Направления" />
  </l:SizeableTabControl.ItemsSource>
  <l:SizeableTabControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Path=Наименование}" />
    </DataTemplate>
  </l:SizeableTabControl.ItemTemplate>
  <l:SizeableTabControl.ContentTemplate>
    <DataTemplate>
      <c:SStackPanel SplitterWidth="3" SplitterBrush="DarkGray">
        <c:SStackPanel.Template>
          <ControlTemplate>
            <l:ПанельСтанции Станция="{Binding}">
            </l:ПанельСтанции>
          </ControlTemplate>
        </c:SStackPanel.Template>
        <c:SStackPanel.Items>
          <Binding Path="Станции" />
        </c:SStackPanel.Items>
      </c:SStackPanel>
    </DataTemplate>
  </l:SizeableTabControl.ContentTemplate>
</l:SizeableTabControl>


SizeableTabControl — немного изменённый TabControl с возможностью изменения размера панели вкладок GridSplitter'ом
SStackPanel — тот самый UserControl
в общем как-то так... не работает. Да, вкладки с направлениями создаются, но не более.
Re[7]: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 14.07.10 12:32
Оценка:
Здравствуйте, dx.dash, Вы писали:

DD>
DD><l:SizeableTabControl x:Name="панельНаправлений" TabStripPlacement="Left" Grid.Row="1">
DD>  <l:SizeableTabControl.Размер>
DD>    <Binding Source="{x:Static Application.Current}" Path="Настройки.ШиринаПанелиНаправлений" Mode="TwoWay" />
DD>  </l:SizeableTabControl.Размер>
DD>  <l:SizeableTabControl.ItemsSource>
DD>    <Binding Source="{x:Static Application.Current}" Path="Конфигурация.Направления" />
DD>  </l:SizeableTabControl.ItemsSource>
DD>  <l:SizeableTabControl.ItemTemplate>
DD>    <DataTemplate>
DD>      <TextBlock Text="{Binding Path=Наименование}" />
DD>    </DataTemplate>
DD>  </l:SizeableTabControl.ItemTemplate>
DD>  <l:SizeableTabControl.ContentTemplate>
DD>    <DataTemplate>
DD>      <c:SStackPanel SplitterWidth="3" SplitterBrush="DarkGray">
DD>        <c:SStackPanel.Template>
DD>          <ControlTemplate>
DD>            <l:ПанельСтанции Станция="{Binding}">
DD>            </l:ПанельСтанции>
DD>          </ControlTemplate>
DD>        </c:SStackPanel.Template>
DD>        <c:SStackPanel.Items>
DD>          <Binding Path="Станции" />
DD>        </c:SStackPanel.Items>
DD>      </c:SStackPanel>
DD>    </DataTemplate>
DD>  </l:SizeableTabControl.ContentTemplate>
DD></l:SizeableTabControl>
DD>


DD>SizeableTabControl — немного изменённый TabControl с возможностью изменения размера панели вкладок GridSplitter'ом

DD>SStackPanel — тот самый UserControl
DD>в общем как-то так... не работает. Да, вкладки с направлениями создаются, но не более.
Гляди, ты задаешь, что SStackPanel.Items следует брать из списка "Станции". А в шаблоне SStackPanel.Template ты почему-то указываешь l:ПанельСтанции, что станция — это {Binding}. Есть подозрение, что здесь нестыковка. И, кстати, все ошибки привязки пишутся в окно Output, посмотри туда, может там будет сообщение о не сработавшем binding-е.
Re[8]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 15.07.10 04:06
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Гляди, ты задаешь, что SStackPanel.Items следует брать из списка "Станции". А в шаблоне SStackPanel.Template ты почему-то указываешь l:ПанельСтанции, что станция — это {Binding}. Есть подозрение, что здесь нестыковка. И, кстати, все ошибки привязки пишутся в окно Output, посмотри туда, может там будет сообщение о не сработавшем binding-е.


Вот так работает (ListBox вместо SStackPanel):
<ListBox>
  <ListBox.ItemTemplate>
    <DataTemplate>
      <l:ПанельСтанции Станция="{Binding}" />
    </DataTemplate>
  </ListBox.ItemTemplate>
  <ListBox.ItemsSource>
    <Binding Path="Станции" />
  </ListBox.ItemsSource>
</ListBox>


А шаблон SStackPanel я указал просто как единственно доступный в этом контроле. Но мне нужен не Template, а ItemTemplate, а соответственно SStackPanel производный от ItemsControl, что пока не удаётся сделать по указанным в сообщении выше причинам.
Re[9]: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 15.07.10 06:46
Оценка:
Здравствуйте, dx.dash, Вы писали:

DD>А шаблон SStackPanel я указал просто как единственно доступный в этом контроле. Но мне нужен не Template, а ItemTemplate, а соответственно SStackPanel производный от ItemsControl, что пока не удаётся сделать по указанным в сообщении выше причинам.

Хорошо, а как тогда этот SStackPanel вообще настраивается? Как-то же ему задается, что показывать...
Re[10]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 15.07.10 07:07
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM>Хорошо, а как тогда этот SStackPanel вообще настраивается? Как-то же ему задается, что показывать...


SStackPanel показывает коллекцию UIElement, которая записывается в SStackPanel.Items. Шаблон для отображаемых элементов я настроить не могу. Приходится использовать конвертер.
Re[11]: [WPF 3.5] Binding с использованием конвертера
От: MxMsk Португалия  
Дата: 15.07.10 07:32
Оценка:
Здравствуйте, dx.dash, Вы писали:

DD>Здравствуйте, MxMsk, Вы писали:

MM>>Хорошо, а как тогда этот SStackPanel вообще настраивается? Как-то же ему задается, что показывать...
DD>SStackPanel показывает коллекцию UIElement, которая записывается в SStackPanel.Items. Шаблон для отображаемых элементов я настроить не могу. Приходится использовать конвертер.
Ах вот оно что... Тогда могу посоветовать два варианта. Нет, три!
  1. Нормально переписать контрол, но это видимо нельзя, да
  2. Написать свою коллекцию. Эта коллекция должна поддерживать INotifyCollectionChanged и сама должна следить за изменением источника данных. Эту коллекцию будет возвращать конвертер.
  3. В самой модели данных сделать так, что при изменении состава коллекции, она будет полностью пересоздаваться и оповещать об изменении свойства. Тогда на это сможет реагировать Binding.
Re[12]: [WPF 3.5] Binding с использованием конвертера
От: dx.dash  
Дата: 15.07.10 07:53
Оценка:
Здравствуйте, MxMsk, Вы писали:

MM> Нормально переписать контрол

MM> Написать свою коллекцию.

Придётся выбрать один из этих вариантов.

Спасибо за уделённое время и советы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.