none
How to bind a VisualBrush to A Image in the ItemsTemplate of a ListBox RRS feed

  • 问题

  • Hello everyone! I have some trouble to bind a VisualBrush to A Image in the ItemsTemplate of a ListBox

    i get a static List<string> in the MainWindow:

    static List<string> slUrl = new List<string>();

    slUrl.add(http://www.abc.com/a.jpg);

    slUrl.add(http://www.abc.com/b.jpg);

    ..

    then I want to show these pictures in a ListBox:

                <ListBox Name="lbPic" ItemsSource="{x:Static local:MainWindow.slUrl}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
       <Image Height="18" Width="32" source = "{Binding}"/>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>

    Now I want to show the Image in a bigger size when I select the Items of the ListBox, because the pictrue is not from local, I don't want to load them again,
    so I use a Canvas with VisualBrush, and want to bing the visual to the ListBox's images:

            <Canvas>
                <Canvas.Background>
                    <VisualBrush Visual="{Binding ElementName=lbPic, Path=SelectedItem, Converter={StaticResource vImgCv}}">      
                    </VisualBrush>               
                </Canvas.Background>
            </Canvas>

    I want to used a Converter(vImgCv) to Convert the SelectedItem to the Image selected, but I don't know how to do. maybe its not a good Idea, and I want to know what should I do

    2011年9月10日 12:58

答案

  • If you want to loop the VisualTree, refer to below code:

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
    
            if (value != null)
            {
                
                ListBox temp = (ListBox)GetDescendantByType(App.Current.MainWindow, typeof(ListBox));
                ListBoxItem curListboxItem = (ListBoxItem)(temp.ItemContainerGenerator.ContainerFromIndex(temp.SelectedIndex));
               // Image temp2 = (Image)GetDescendantByType(curListboxItem, typeof(Image));
    
                return curListboxItem;
            }
    
            else
                return null;
        }
    
        public static Visual GetDescendantByType(Visual element, Type type)
        {
            if (element == null) return null;
            if (element.GetType() == type) return element;
            Visual foundElement = null;
            if (element is FrameworkElement)
                (element as FrameworkElement).ApplyTemplate();
            for (int i = 0;
                i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
                foundElement = GetDescendantByType(visual, type);
                if (foundElement != null)
                    break;
            }
            return foundElement;
        }
    

    Above method will return a ListBoxItem, if you want to return the Image, you could loop the VisualTree to find the Image:

    Image image = (Image)GetDescendantByType(curListboxItem, typeof(Image));
    


    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 nobuyaki 2011年9月17日 2:55
    2011年9月14日 9:07
    版主

全部回复

  • Hi nobuyaki,

    In your Converter, you could return an Image, for example:

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value != null)
            {
                Image test = new Image();
                test.Source = new BitmapImage(new Uri(value.ToString()));
                return test;
            }
    
            else
                return null;
        }
    

     

     

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年9月13日 8:03
    版主
  • Thanks for replying! but what I want was not to Create a new image, If I want to do so , I will use a Image just like:

    <Image source ="{Binding ElementName=lbPic, Path=SelectedItem}"/>

    but when I select the lbPic,  it should reload the picture from Internet one more time. So I want to use the VisualBrush to show the picture that had already loaded in the ListBox. But I have to find out the handle of that picture first, then I want to know how can I convert the SelectedItem of the ListBox to the image I wanted, using something like VisualTreeHelper

    2011年9月14日 8:25
  • If you want to loop the VisualTree, refer to below code:

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
    
            if (value != null)
            {
                
                ListBox temp = (ListBox)GetDescendantByType(App.Current.MainWindow, typeof(ListBox));
                ListBoxItem curListboxItem = (ListBoxItem)(temp.ItemContainerGenerator.ContainerFromIndex(temp.SelectedIndex));
               // Image temp2 = (Image)GetDescendantByType(curListboxItem, typeof(Image));
    
                return curListboxItem;
            }
    
            else
                return null;
        }
    
        public static Visual GetDescendantByType(Visual element, Type type)
        {
            if (element == null) return null;
            if (element.GetType() == type) return element;
            Visual foundElement = null;
            if (element is FrameworkElement)
                (element as FrameworkElement).ApplyTemplate();
            for (int i = 0;
                i < VisualTreeHelper.GetChildrenCount(element); i++)
            {
                Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
                foundElement = GetDescendantByType(visual, type);
                if (foundElement != null)
                    break;
            }
            return foundElement;
        }
    

    Above method will return a ListBoxItem, if you want to return the Image, you could loop the VisualTree to find the Image:

    Image image = (Image)GetDescendantByType(curListboxItem, typeof(Image));
    


    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • 已标记为答案 nobuyaki 2011年9月17日 2:55
    2011年9月14日 9:07
    版主
  • cool ! That's what i wanted, thank u!
    2011年9月17日 2:57