简体   繁体   中英

WPF ListBox: Change border per item according boolean value

In my app I load image and verify I haven't too much blobs.

In additional, I put all images I loaded in list box and all image have a border. Now, I want to change border color pet item according the Boolean value (true or false according numbers of blobs and their size). If my image passed the border should be green, else red.

my relevent code:

public List<String> ImagePath = new List<String>();

public MainWindow()
{
    InitializeComponent();
    lb_Images.ItemsSource = ImagePath;
}

private void bu_addImage_Click(object sender, RoutedEventArgs e)
{
    addImageToListBox();
}

private void addImageToListBox()
{
    String imagePath = getImage();
    // verfiy img haven't too much blobs
    Boolean passed = imagePassed(imagePath);

    // add the image to the list box
    //   I want to change border according passed value
    //   True - green; False- red.
    ImagePath.Add(imagePath);
    lb_Images.Items.Refresh();
}

XAML:

<Window x:Class="forQuestionWPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="216" Width="519">

    <Window.Resources>
        <DataTemplate x:Key="ImageGalleryDataTemplate">
            <Grid>
                <Border BorderBrush="Green" BorderThickness="2"  Width="120" Height="120" Padding="5" Margin="5" CornerRadius="6">
                    <Image Source="{Binding}" Stretch="Fill"  HorizontalAlignment="Center">
                        <Image.ToolTip>
                            <Grid>
                                <Image Source="{Binding}" Stretch="Fill" HorizontalAlignment="Center" Height="200" Width="200" />
                            </Grid>
                        </Image.ToolTip>
                    </Image>
                </Border>
            </Grid>
        </DataTemplate>

        <ItemsPanelTemplate x:Key="ImageGalleryItemsPanelTemplate">
            <UniformGrid Rows="1" Columns="25" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
        </ItemsPanelTemplate>
    </Window.Resources>



    <Grid>
        <Canvas Height="177" HorizontalAlignment="Left" Name="canvas1" VerticalAlignment="Top" Width="497">

            <ListBox Canvas.Left="6" Canvas.Top="5" Height="166" Name="lb_Images" Width="441"  
                 ItemTemplate="{StaticResource ImageGalleryDataTemplate}"
                 ItemsSource="{Binding Path=ImagePath}"
                 ItemsPanel="{StaticResource ImageGalleryItemsPanelTemplate}">
            </ListBox>

            <Button Canvas.Left="453" Canvas.Top="26" Content="Add" Height="64" Name="bu_addImage" Width="38" Click="bu_addImage_Click" />
        </Canvas>
    </Grid>
</Window>

For example, in the below image latest two items need to be with red border: 在此处输入图片说明

Thank you on any help! AsfK

Instead of binding to imagePath (string) you can define a class:

public class ImageStuff {
  public string ImagePath {get; set;}
  public bool Passed {get; set;}
}

and add instance of this to the listbox.

Then, you can use a converter for your border like this:

<Border BorderThickness="2"  Width="120" Height="120" Padding="5" Margin="5" CornerRadius="6" BorderBrush="{Binding Path=Passed, Mode=OneWay, Converter={StaticResource borderConverter}}">

where borderConverter is something like this:

public class borderConverter : IValueConverter
{
  public object Convert(object value, Type targetType, 
    object parameter, CultureInfo culture)
{
    if (value is bool)
    {
      if (!(bool)value == true)
        return new SolidColorBrush(Colors.Red);
    }

    return new SolidColorBrush(Colors.Green);
}

public object ConvertBack(object value, Type targetType, 
    object parameter, CultureInfo culture)
{
    throw NotImplementedException();
}
}

You have to include borderConverter in your resources like this:

<Window.Resources>
  <src:borderConverter x:Key="borderConverter" />
</Window.Resources>

where src is the namespace.

If you want to change property of ImageStuff class dinamically you have to implement INotifyPropertyChanged so the binding will be updated.

You neeed to write BoolToColorConverter for this purpose. Find following converter code.

public sealed class BoolToColorConverter : IValueConverter
{
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool bValue = (bool)value;
        if (bValue)
            return Color.Green;
        else
            return Color.Red;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Color color = (Color)value;

        if (color == Color.Green)
            return true;
        else
            return false;

    }
}

You can do it without Converter , just add DataTrigger with Tag property to DataTemplate. This can affect to the performance because the Converter will work little much longer.

Add this class:

public class MyImage
{
    public string ImagePath
    {
        get; 
        set; 
    }

    public bool Flag
    { 
        get;
        set;
    }
}

And in code-behind use like this:

public List<MyImage> ImagePath = new List<MyImage>();

Full example:

XAML

<DataTemplate x:Key="ImageGalleryDataTemplate">
    <Grid>
        <Border Name="MyBorder" BorderBrush="#FFFF9800" BorderThickness="1" Width="120" Height="120" Padding="5" Margin="5" CornerRadius="6">
            <Image Name="MyImage" Tag="{Binding Path=Flag}" Source="{Binding Path=ImagePath}" Stretch="Fill" HorizontalAlignment="Center">
                <Image.ToolTip>
                    <Grid>
                        <Image Source="{Binding Path=ImagePath}" Stretch="Fill" HorizontalAlignment="Center" Height="200" Width="200" />
                    </Grid>
                </Image.ToolTip>
            </Image>
        </Border>
    </Grid>

    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=Tag, ElementName=MyImage}" Value="True">
            <Setter TargetName="MyBorder" Property="BorderBrush" Value="Red" />
        </DataTrigger>

        <DataTrigger Binding="{Binding Path=Tag, ElementName=MyImage}" Value="False">
            <Setter TargetName="MyBorder" Property="BorderBrush" Value="Green" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

Code-behind

public partial class MainWindow : Window
{
    int imageNumber = 0;
    public List<MyImage> ImagePath = new List<MyImage>();

    public MainWindow()
    {
        InitializeComponent();
        lb_Images.ItemsSource = ImagePath;
    }

    private void bu_addImage_Click(object sender, RoutedEventArgs e)
    {
        addImageToListBox();
    }

    private void addImageToListBox()
    {
        imageNumber++;
        if (imageNumber == 4) imageNumber = 0;
        string directoryPath = AppDomain.CurrentDomain.BaseDirectory;

        // load input image
        string ImageFilename = directoryPath + "img";
        ImageFilename += imageNumber.ToString();
        ImageFilename += ".jpg";

        ImagePath.Add(new MyImage 
                      { 
                          ImagePath = ImageFilename, 
                          Flag = false 
                      }); 

        lb_Images.Items.Refresh();
    }
}

public class MyImage
{
    public string ImagePath
    {
        get; 
        set; 
    }

    public bool Flag
    { 
        get;
        set;
    }
}

In order to the properties of MyImage class successfully changed, you need to implement the INotifyPropertyChanged interface.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM