[WPF] Image Source
От: Sergey_BG Россия  
Дата: 25.01.11 10:06
Оценка:
Всем привет. Подскажите пожалуйста.


       <ListBox DataContext="{Binding Source={StaticResource curFolderKey}, Path=Files}" ItemsSource="{Binding}" Grid.Row="1" Grid.RowSpan="2"
            local:DataSetter.Item="{Binding Source={StaticResource curFolderKey}}"
            local:DataSetter.Path="File"
            local:DataSetter.Value="{Binding Path=SelectedItem, RelativeSource={RelativeSource Self}}"
            >
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="ContentTemplate">
                        <Setter.Value>
                            <DataTemplate>
                                <Image Name="image" Source="{Binding Path=Path}" Margin="2" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" Height="50" Width="50" />
                            </DataTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>


1) curFolderKey — ресурс в App. Можно ли как нибудь его свойство связать с ListBox.CurrentItem которое есть свойство только для чтения. curFolderKey не видит ListBox. ListBox не связывается с curFolderKey так как свойство только для чтения. На текущий момент сделал attached dependency property, и с их помощью это делаю.
2) Хочу чтоб картинки обновлялись асинхронно. Т.е. как зачитает их из файла, так и покажет, а я пока они не загружены мог продолжать работу с UI. Но установка в биндинг IsAsync не помогает.
3) Сделал загрузку BitmapSource непосредственно в моих классах в параллельном потоке. Устанавливаю dependency property ImageSource моего класса, к которому теперь привязано изображение
<Image Name="image" Source="{Binding Path=ImageSource}" Margin="2" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" Height="50" Width="50" />

Но Image не обновляется после изменения этого свойства. Остается пустым. Как заставить его обновиться? UpdateSourceTrigger=PropertyChanged не помогает.
Сергей
Re: [WPF] Image Source
От: Codechanger Россия  
Дата: 25.01.11 10:27
Оценка:
Здравствуйте, Sergey_BG, Вы писали:

S_B>Всем привет. Подскажите пожалуйста.



S_B>
S_B>       <ListBox DataContext="{Binding Source={StaticResource curFolderKey}, Path=Files}" ItemsSource="{Binding}" Grid.Row="1" Grid.RowSpan="2"
S_B>            local:DataSetter.Item="{Binding Source={StaticResource curFolderKey}}"
S_B>            local:DataSetter.Path="File"
S_B>            local:DataSetter.Value="{Binding Path=SelectedItem, RelativeSource={RelativeSource Self}}"
            >>
S_B>            <ListBox.ItemsPanel>
S_B>                <ItemsPanelTemplate>
S_B>                    <StackPanel Orientation="Horizontal" />
S_B>                </ItemsPanelTemplate>
S_B>            </ListBox.ItemsPanel>
S_B>            <ListBox.ItemContainerStyle>
S_B>                <Style TargetType="{x:Type ListBoxItem}">
S_B>                    <Setter Property="ContentTemplate">
S_B>                        <Setter.Value>
S_B>                            <DataTemplate>
S_B>                                <Image Name="image" Source="{Binding Path=Path}" Margin="2" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" Height="50" Width="50" />
S_B>                            </DataTemplate>
S_B>                        </Setter.Value>
S_B>                    </Setter>
S_B>                </Style>
S_B>            </ListBox.ItemContainerStyle>
S_B>        </ListBox>
S_B>


S_B>1) curFolderKey — ресурс в App. Можно ли как нибудь его свойство связать с ListBox.CurrentItem которое есть свойство только для чтения. curFolderKey не видит ListBox. ListBox не связывается с curFolderKey так как свойство только для чтения. На текущий момент сделал attached dependency property, и с их помощью это делаю.

S_B>2) Хочу чтоб картинки обновлялись асинхронно. Т.е. как зачитает их из файла, так и покажет, а я пока они не загружены мог продолжать работу с UI. Но установка в биндинг IsAsync не помогает.
S_B>3) Сделал загрузку BitmapSource непосредственно в моих классах в параллельном потоке. Устанавливаю dependency property ImageSource моего класса, к которому теперь привязано изображение
S_B>
<Image Name="image" Source="{Binding Path=ImageSource}" Margin="2" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" Height="50" Width="50" />

S_B>Но Image не обновляется после изменения этого свойства. Остается пустым. Как заставить его обновиться? UpdateSourceTrigger=PropertyChanged не помогает.

Напишите юзкейс,который вы хотите реализовать. Что-то мне подсказывает, что CurrentItem вам не очень поможет.
Re: [WPF] Image Source
От: Sergey_BG Россия  
Дата: 25.01.11 10:35
Оценка:
Здравствуйте, Sergey_BG, Вы писали:

S_B>3) Сделал загрузку BitmapSource непосредственно в моих классах в параллельном потоке. Устанавливаю dependency property ImageSource моего класса, к которому теперь привязано изображение

S_B>
<Image Name="image" Source="{Binding Path=ImageSource}" Margin="2" Stretch="Uniform" HorizontalAlignment="Left" VerticalAlignment="Center" Height="50" Width="50" />


Третий вопрос отпадает, у меня была ошибка.
Сергей
Re[2]: [WPF] Image Source
От: Sergey_BG Россия  
Дата: 25.01.11 10:47
Оценка:
Здравствуйте, Codechanger, Вы писали:

C>Напишите юзкейс,который вы хотите реализовать. Что-то мне подсказывает, что CurrentItem вам не очень поможет.

SelectedItem — здесь ничему не помогает. Просто я хочу к нему забиндить поле curFolderKey.File. А к этому полю забиндить другие компоненты. Т.е. есть глобальный класс на уровне приложения. А у него я обновляю свойства: текущая папка, текущий файл. А уже к ним биндю все контролы которым эта информация нужна.
Сергей
Re[3]: [WPF] Image Source
От: Codechanger Россия  
Дата: 25.01.11 10:53
Оценка:
Здравствуйте, Sergey_BG, Вы писали:

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


C>>Напишите юзкейс,который вы хотите реализовать. Что-то мне подсказывает, что CurrentItem вам не очень поможет.

S_B>SelectedItem — здесь ничему не помогает. Просто я хочу к нему забиндить поле curFolderKey.File. А к этому полю забиндить другие компоненты. Т.е. есть глобальный класс на уровне приложения. А у него я обновляю свойства: текущая папка, текущий файл. А уже к ним биндю все контролы которым эта информация нужна.

А теперь по-русски, пожалуйста. У вас в списке показывается коллекция объектов? И опишите действия, которые вы с ней планируете и как ее хотите отображать.
Re[4]: [WPF] Image Source
От: Sergey_BG Россия  
Дата: 25.01.11 11:26
Оценка:
Здравствуйте, Codechanger, Вы писали:
C>А теперь по-русски, пожалуйста. У вас в списке показывается коллекция объектов? И опишите действия, которые вы с ней планируете и как ее хотите отображать.

Программа. В ней несколько фреймов. Один фрейм содержит TreeView для отображения дерева папок. Другой фрейм — ListBox для отображения файлов.
Для MVVM создана бизнес структура объектов drive, folder, file и их DriveViewModel и т.п.

Есть класс CurrentFolder, который содержит CLR свойство drives из которого TreeView читает стартовые данные (ItemsSource="{Binding ... ), и DependencyProperty Folder, File в которых я хочу хранить текущую выбранную папку и файл.

При выборе элемента в TreeView или ListBox, как в потомках ItemsControl, изменяется свойство SelectedItem.

Я хотел сделать
<Application.Resources> <local:CurrentFolder x:Key="curFolderKey" Folder={Binding на TreeView.SelectedItem} File={Binding на ListBox.SelectedItem}/> <Application.Resources />


Когда это не получилось, я попробовал сделать
<TreeView SelectedItem={Binding Source={StaticResource curFolderKey}, Path=Folder, Mode=OneWaySource}

<ListBox SelectedItem={Binding Source={StaticResource curFolderKey}, Path=File, Mode=OneWaySource}


Но это тоже не получилось.

Тогда я написал свой класс DataSetter который делает то что мне надо.

Вопрос 1), может быть можно сделать привязку данных как нибудь, без вспомогательного класса DataSetter?
____________________________________________________________________________
Вопрос номер 2. Он не относится никак к вопросу номер 1.
ListBox связан с коллекцией объектов. ListBox показывает коллекцию картинок. У каждой картинки свойство Source связано со строковым свойством Path связанных данных.
Таким образом ListBox создает коллекцию контейнеров ListBoxItem. В каждый контейнер в соответствии с шаблоном создается Image который грузит картинку из связанного пути. Пока все картинки не загрузятся программа полностью застывает.
Хотелось бы, чтоб загрузка картинок происходила как нибудь фоном. Можно ли это сделать?

На текущий момент сделал привязку к свойству ViewModel класса, а его уже гружу сам в параллельном потоке асинхронно.
___________________________________________________________________________

Извиняюсь если вопросы тупые, изучаю WPF.
Сергей
Re[5]: [WPF] Image Source
От: Sergey_BG Россия  
Дата: 04.02.11 12:10
Оценка:
По пункту 2 сделал следующее. 1) Виртуализация элементов. 2) В шаблоне по загрузке/выгрузке картинки устанавливаю поле Tag в строку "True" / "False". Эту строку копирую в свойство FileViewModel.IsShowed. А оно загружает/выгружает источник картинки.
Интересно, можно сделать это проще. Где-то я слышал что асинхронная загрузка данных делается за минуту.

<Application.Resources>
    <local:CurrentFolder x:Key="curFolderKey" />
</Application.Resources>


class CurrentFolder
{
    public ObservableCollection<FileViewModel> Files;
    public FileViewModel File;
}

class File
{
    public System.Windows.Media.ImageSource ImageSource; // источник данных для картинки
    public string IsShowed; // если True в параллельном потоке загрузить ImageSource
}

class DataSetter
{
    object Item; // Attached dependency properties Объект, кому присвоить
    string Path; // Свойство
    object Value;// Значение которое необходимо присвоить свойству объекта
}


<ListBox DataContext="{Binding Source={StaticResource curFolderKey}, Path=Files}" ItemsSource="{Binding}"
    VirtualizingStackPanel.IsVirtualizing="True" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <Image x:Name="image" Source="{Binding Path=ImageSource}" Margin="2" Stretch="Uniform"
                    HorizontalAlignment="Left" VerticalAlignment="Center"
                    Height="50" Width="50"
                    local:DataSetter.Item="{Binding}"
                    local:DataSetter.Path="IsShowed"
                    local:DataSetter.Value="{Binding Path=Tag, RelativeSource={RelativeSource Self}}"
                />
            </StackPanel>
            <DataTemplate.Triggers>
                <EventTrigger RoutedEvent="Image.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="image"
                                Storyboard.TargetProperty="Tag"
                                Duration="0:0:0" FillBehavior="HoldEnd">
                                <DiscreteStringKeyFrame Value="True" KeyTime="0:0:0" />
                            </StringtAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="FrameworkElement.Unloaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <StringAnimationUsingKeyFrames
                                Storyboard.TargetName="image"
                                Storyboard.TargetProperty="Tag"
                                Duration="0:0:0" FillBehavior="HoldEnd">
                                <DiscreteStringKeyFrame Value="False" KeyTime="0:0:0" />
                            </StringAnimationUsingKeyFrames>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
Сергей
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.