问:
React Native, UI Kitten Input custom style on default and onFocus states
I need some help about creating a custom input style on default and onFocus states.

```<code>import React, {useState} from 'react';
import {
  StyleSheet,
  View,
} from 'react-native';
import {
  Input,
  Layout,
} from '@ui-kitten/components';

export const CustomInputExample = () => {
  const [ focusStatus, setFocusStatus ] = useState(false)

  const onMouseEnter = () => {
     setFocusStatus(true)
  }

  const onMouseLeave = () => {
     setFocusStatus(false)
  }

  return (
    <Layout>
      <Input
        style={focusStatus ? styles.customStyle : styles.basicStyle}
        status={focusStatus ? 'success' : 'basic'}
        placeholder='Success'
        onMouseEnter={onMouseEnter}
        onMouseLeave={onMouseLeave}
      />
    </Layout>
  );
};

const styles = StyleSheet.create({
  basicStyle: {
    borderColor: grey,
  },
  customStyle: {
    borderColor: '#3CB46E'
  },
});

</code>```

But, none of the methods are working in my case. I've tried other InputProps like focus, onTextFieldFocus, onTextFieldBlur...May be I do not know how to use them.

Also this is the error from ts =>

Property 'onMouseEnter' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Readonly<...> & Readonly<...>'.ts(2322)

Any help can be grateful.

答:
At last, I've found the solution. I'am writing to help others who uses react-native-ui-kitten.

InputComponent implements WebEventResponderCallbacks interface so =>

```<code>export interface WebEventResponderCallbacks {
    onMouseEnter?: () => void;
    onMouseLeave?: () => void;
    onFocus?: () => void;
    onBlur?: () => void;
}
</code>```

I don't know the reason why onMouseEnter, onMouseLeave or any other methods of InputComponent have no use but onFocus and onBlur are working.

Body:
I need some help about creating a custom input style on default and onFocus states.

import React, {useState} from 'react';
import {
  StyleSheet,
  View,
} from 'react-native';
import {
  Input,
  Layout,
} from '@ui-kitten/components';

export const CustomInputExample = () => {
  const [ focusStatus, setFocusStatus ] = useState(false)

  const onMouseEnter = () => {
     setFocusStatus(true)
  }

  const onMouseLeave = () => {
     setFocusStatus(false)
  }

  return (
    <Layout>
      <Input
        style={focusStatus ? styles.customStyle : styles.basicStyle}
        status={focusStatus ? 'success' : 'basic'}
        placeholder='Success'
        onMouseEnter={onMouseEnter}
        onMouseLeave={onMouseLeave}
      />
    </Layout>
  );
};

const styles = StyleSheet.create({
  basicStyle: {
    borderColor: grey,
  },
  customStyle: {
    borderColor: '#3CB46E'
  },
});

But, none of the methods are working in my case. I've tried other InputProps like focus, onTextFieldFocus, onTextFieldBlur...May be I do not know how to use them.

Also this is the error from ts =>

Property 'onMouseEnter' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Readonly<...> & Readonly<...>'.ts(2322)

Any help can be grateful.

Body:
At last, I've found the solution. I'am writing to help others who uses react-native-ui-kitten.

InputComponent implements WebEventResponderCallbacks interface so =>

export interface WebEventResponderCallbacks {
    onMouseEnter?: () => void;
    onMouseLeave?: () => void;
    onFocus?: () => void;
    onBlur?: () => void;
}

I don't know the reason why onMouseEnter, onMouseLeave or any other methods of InputComponent have no use but onFocus and onBlur are working.


来源: stackexchange

问:
Hibernate click event binding with jQuery
I a code similar to the following

```<code>$(element).click(function() {
$(slider).slide();
});
</code>```

What I want to do is to deactivate the click event until the sliding finish (or more precisely the function complete) so that users don't abuse it. How can I do that?

答:
Something has to trigger sliding, so deactivating won't be an option. Instead you could start sliding on click and perform whatever other operations you need to in the slide()'s callback function:

```<code>$(element).click(function() {
    $(slider).slide(function(){ // Do something additional here});
});
</code>```

Hope i understood your question right.

P.S. Not quite sure if jquery has slide() effect. It sure has slideToggle, slideUp and slideDown, but haven't heard of slide

Try the below code for your purposes.

```<code>$(element).click(function() {
    $(element).attr("disabled", "disabled");
    $(slider).slide(function(){ $(element).removeAttr("disabled"); });
});
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I a code similar to the following

$(element).click(function() {
$(slider).slide();
});

What I want to do is to deactivate the click event until the sliding finish (or more precisely the function complete) so that users don't abuse it. How can I do that?

Body:
Something has to trigger sliding, so deactivating won't be an option. Instead you could start sliding on click and perform whatever other operations you need to in the slide()'s callback function:

$(element).click(function() {
    $(slider).slide(function(){ // Do something additional here});
});

Hope i understood your question right.

P.S. Not quite sure if jquery has slide() effect. It sure has slideToggle, slideUp and slideDown, but haven't heard of slide

Try the below code for your purposes.

$(element).click(function() {
    $(element).attr("disabled", "disabled");
    $(slider).slide(function(){ $(element).removeAttr("disabled"); });
});


问:
WPF MVVM itemsControl and button command does not work?
I have got a problem with my WPF MVVM application.
I have got a view (CaisseView.xaml) and its ViewModel (CaisseViewModel.cs which is used as Datacontext of the View called since another .cs).
Into my view i am using an itemsControl in order to have a button for each element of a observablecollection of a Model. Moreover into my view I have got an ListView. I want that every time a button of the itemsControl is clicked a new line appears into my Lisview.
This last thing is what it does not work!!
Using debug I enter into my command, the command add an object into my observable collection but the app does not actualize the View.

Into my ViewModel, I am using INotifyPropertyChanged, RelayCommand and ICommand.

I let you my code.
Can you help me with my matter ???
thanks:

My View :

```<code><UserControl x:Class="LMarket.Views.CaisseView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:local="clr-namespace:LMarket.Views"
             xmlns:localM="clr-namespace:LMarket.Models"
             xmlns:localModel="clr-namespace:LMarket.ViewModels"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             mc:Ignorable="d">
    <UserControl.Resources>
        <localModel:CaisseViewModel x:Key="CaisseViewModel"/>
        <localM:ProduitDuStock x:Key="ProduitDuStockModel"/>
    </UserControl.Resources>
    <Grid Name="MainGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Image Cursor="Hand" Source="/Resources/homepage.png" Width="32" Height="32" HorizontalAlignment="Left" Margin="15,10" Grid.Row="0">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <i:InvokeCommandAction Command="{Binding DataContext.OnHomeCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Image>
        <Image Cursor="Hand" Source="/Resources/LogOut.png" Width="32" Height="32" HorizontalAlignment="Right" Margin="15,10" Grid.Row="0">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseLeftButtonDown">
                    <i:InvokeCommandAction Command="{Binding DataContext.BackConnectionCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Image>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderThickness="2" BorderBrush="Azure" Margin="5,5,1,5">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="50"/>
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="50" />
                        <RowDefinition Height="50"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.Row="0" Background="#FFC2E0ED">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                            <Image Cursor="Hand" VerticalAlignment="Center"  Width="32" Height="32" Source="/Resources/files-and-folders.png"/>
                            <Image Cursor="Hand" VerticalAlignment="Center" Margin="10,0" Width="32" Height="32" Source="/Resources/cancel.png"/>
                        </StackPanel>
                    </Grid>
                    <ListView Grid.Row="1" Margin="5" SelectionMode="Single"
                              HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=LstProducts, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                        <ListView.ItemTemplate>
                            <DataTemplate DataType="localM:ProduitDuStock">
                                <StackPanel Margin="2" MinWidth="244">
                                    <StackPanel.Resources>
                                        <Style TargetType="{x:Type StackPanel}">
                                           <!-- <Style.Triggers>
                                                <DataTrigger Binding="{Binding Path=Selected}" Value="True">
                                                    <Setter Property="Background" Value="LightBlue"/>
                                                </DataTrigger>
                                        </Style.Triggers> -->
                                        </Style>
                                    </StackPanel.Resources>
                                    <DockPanel >
                                        <TextBlock FontWeight="Bold" Text="Produit: " DockPanel.Dock="Left" Margin="5,0,5,0"/>
                                        <TextBlock Text="  " />
                                        <TextBlock Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Green" FontWeight="Bold" />
                                    </DockPanel>
                                </StackPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                    <DockPanel Grid.Row="2" Margin="5" Background="#FF296B88">
                        <Label Content="TOTAL" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="14" FontWeight="Bold" FontFamily="Rockwell Condensed" Foreground="#FFF2FF5A" />
                        <Label Content="$$" HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="14" FontWeight="Bold" FontFamily="Rockwell Condensed" Foreground="#FFF2FF5A" />
                    </DockPanel>
                    <Grid Grid.Row="3" Background="#FFC2E0ED">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="2">
                            <Button Cursor="Hand" Width="80" Content="Cuenta %" Background="#FF98ADA8" BorderBrush="#FF4A6DFF" Margin="2,0">
                                <Button.Resources>
                                    <Style TargetType="{x:Type Border}">
                                        <Setter Property="CornerRadius" Value="8"/>
                                    </Style>
                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="Producto %" Background="#FF98ADA8" BorderBrush="#FF4A6DFF" Margin="2,0">
                                <Button.Resources>
                                    <Style TargetType="{x:Type Border}">
                                        <Setter Property="CornerRadius" Value="8"/>
                                    </Style>
                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="-1" Background="#FFDDCF00" BorderBrush="#FF4A6DFF" FontWeight="Bold" FontSize="20">
                                <Button.Resources>
                                    <Style TargetType="{x:Type Border}">
                                        <Setter Property="CornerRadius" Value="8"/>
                                    </Style>
                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="+1" Background="#FF79C837" BorderBrush="#FF4A6DFF" FontWeight="Bold" FontSize="20" Margin="2,0">
                                <Button.Resources>
                                    <Style TargetType="{x:Type Border}">
                                        <Setter Property="CornerRadius" Value="8"/>
                                    </Style>
                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="auto" Content="  Validar para Pagar  " Command="{Binding AddNewProductCommand}" Background="#FF98ADA8" BorderBrush="#FF4A6DFF"  FontSize="19" Margin="80,0,2,0" Foreground="Black">
                                <Button.Resources>
                                    <Style TargetType="{x:Type Border}">
                                        <Setter Property="CornerRadius" Value="8"/>
                                    </Style>
                                </Button.Resources>
                            </Button>
                        </StackPanel>
                    </Grid>
                </Grid>
            </Border>
            <Border Grid.Column="1" BorderThickness="2" BorderBrush="Azure" Margin="1,5,5,5">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" MaxHeight="720"/>
                        <RowDefinition Height="1" />
                    </Grid.RowDefinitions>
                    <ScrollViewer Grid.Row="0" Background="Transparent"
                                  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                        <ItemsControl ItemsSource="{Binding ListOfProducts}" MaxWidth="762">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border Cursor="Hand" CornerRadius="8" Margin="4,3" BorderThickness="1.5" BorderBrush="#FFFDFF00">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FF6F92DC" Offset="1"/>
                                                <GradientStop Color="#FFA6DBFF" Offset="0.534"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <Button BorderBrush="Transparent" Background="Transparent" Command="{Binding Source={StaticResource CaisseViewModel}, Path=AddNewProductCommand}" CommandParameter="{Binding Id}">
                                            <Button.Resources>
                                                <Style TargetType="{x:Type Border}">
                                                    <Setter Property="CornerRadius" Value="8"/>
                                                </Style>
                                            </Button.Resources>
                                            <StackPanel Orientation="Vertical" Margin="2" Width="80" Height="80">

                                                <Image Source="{Binding ProductImageUrl}" Width="40" Height="40" Margin="0,10,0,5"
                                                   HorizontalAlignment="Center"/>

                                            <Label Content="{Binding Surname}" FontWeight="Bold" HorizontalAlignment="Center" FontSize="11"/>
                                        </StackPanel>
                                        </Button>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </ScrollViewer>
                </Grid>
            </Border>
        </Grid>
    </Grid>
</UserControl>

</code>```

And my ViewModel:

```<code>using LMarket.Models;
using LMarket.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Xml;

namespace LMarket.ViewModels
{
    class CaisseViewModel : INotifyPropertyChanged
    {
        //Event for INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged([CallerMemberName] string str = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(str));
        }

        #region Attributs
        private ObservableCollection<ProduitDuStock> listOfProducts;
        private ObservableCollection<ProduitDuStock> lstProducts;
        private ProduitDuStock selectedProduct;
        #endregion
        #region Getter/Setter
        public ObservableCollection<ProduitDuStock> ListOfProducts
        {
            get
            {
                return listOfProducts;
            }
            set
            {
                if (listOfProducts != value)
                {
                    listOfProducts = value;
                }
                NotifyPropertyChanged();
            }
        }
        public ObservableCollection<ProduitDuStock> LstProducts
        {
            get
            {
                return lstProducts;
            }
            set
            {
                if (lstProducts != value)
                {
                    lstProducts = value;
                }
                NotifyPropertyChanged();
            }
        }
        public ProduitDuStock SelectedProduct
        {
            get
            {
                return selectedProduct;
            }
            set
            {
                if (selectedProduct != value)
                {
                    selectedProduct = value;
                    NotifyPropertyChanged();
                }
            }
        }

        #endregion

        #region Constructeur
        public CaisseViewModel()
        {
            ListOfProducts = new ObservableCollection<ProduitDuStock>();
            LstProducts = new ObservableCollection<ProduitDuStock>();
            toto();
            //Lecture du fichier ou son enregistrer les données du stock (En local sur un .xml)
            try
            {
                //Ouverture du document XML
                XmlDocument xmlDoc = new XmlDocument();
                string Path = Directory.GetCurrentDirectory().ToString();
                Path = Path + "\\Configuration\\Stockes.xml";
                xmlDoc.Load(Path);
                //Recupérer la section des produits
                XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/Stockes/Products/product");
                //Pour chaque produit dans le fichier, créer un objet ProduitDuStock et l'ajouter à l'ObservableCollection.
                foreach (XmlNode node in nodeList)
                {
                    //Creation du nouvel objet
                    ProduitDuStock testProduit = new ProduitDuStock();
                    foreach (XmlAttribute att in node.Attributes)
                    {
                        //Récupération des parametres de l'objet.
                        switch (att.Name)
                        {
                            case "id":
                                testProduit.Id = int.Parse(att.Value);
                                break;
                            case "name":
                                testProduit.Name = att.Value;
                                break;
                            case "pays":
                                testProduit.Pays = att.Value;
                                break;
                            case "surname":
                                testProduit.Surname = att.Value;
                                break;
                            case "quantite":
                                testProduit.Quantite = int.Parse(att.Value);
                                break;
                            case "unitprice":
                                testProduit.UnitPrice = int.Parse(att.Value);
                                break;
                            case "productImageUrl":
                                testProduit.ProductImageUrl = att.Value;
                                break;
                            default:
                                break;
                        }
                    }
                    //Ajouter l'objet créé a notre ObservableCollection.
                    ListOfProducts.Add(testProduit);
                }

            }
            catch (Exception ex)
            {

            }
        }
        #endregion

        #region Command Definition
        //Event RelayCommand Definition
        private RelayCommand addProductToBill = null;
        public ICommand AddProductToBill
        {
            get
            {
                if (addProductToBill == null)
                {
                    addProductToBill = new RelayCommand(OnAddProductToBill);
                }
                return addProductToBill;
            }
        }
        private RelayCommand addNewProductCommand = null;
        public ICommand AddNewProductCommand
        {
            get
            {
                if (addNewProductCommand == null)
                {
                    addNewProductCommand = new RelayCommand(OnAddNewProductCommand);
                }
                return addNewProductCommand;
            }
        }
        #endregion

        #region Command function definition
        //Event lorsque le curseur rentre dans la zone du boutton "Stock"
        private void OnAddNewProductCommand(object obj)
        {
            toto();
        }

        private void OnAddProductToBill(object obj)
        {
            toto();
        }
        #endregion

        #region function
        public void toto()
        {
            ProduitDuStock myAddProductToBill = new ProduitDuStock();
            myAddProductToBill.Name = "trrt";
            LstProducts.Add(myAddProductToBill);
        }
        #endregion
    }
}
</code>```

the important part into the view is the next:

```<code><Button BorderBrush="Transparent" Background="Transparent" Command="{Binding Source={StaticResource CaisseViewModel}, Path=AddNewProductCommand}" CommandParameter="{Binding Id}">
</code>```

remember that this button is defined into a itemsControl ! So the Datacontextof the button is not my viewModel that why I am using a staticResource...

I hope something will help me :) thank you very much.

答:
Welcome to SO! For future reference, you'll have a much better chance of getting your questions answered if you post an MCVE, there's enough unnecessary code in what you posted to put most people here off.

To answer your question, there are actually many things wrong with this code, but the main issue is that you're creating callback handlers of type RelayCommand, yet your command handler (AddProductToBill) expects an object parameter and should thus be of type RelayCommand<object>. (More confusingly, one of your bindings is passing in CommandParameter, while the other is not).

Another thing to avoid is declaring your view model in your resources block, this is generally not done for a variety of reasons (are you sure you're assigning that instance as your DataContext and not declaring a new one?). If you're assigning your DataContext elsewhere then your list elements can bind to it with something like this:

```<code><UserControl ...
    x:Name="_this">
    .
    .
    <!-- Inside ItemsControl.ItemTemplate -->
    <Button
        Command="{Binding ElementName=_this, Path=DataContext.MyHandler}"
        CommandParameter="{Binding}" ... />
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I have got a problem with my WPF MVVM application.
I have got a view (CaisseView.xaml) and its ViewModel (CaisseViewModel.cs which is used as Datacontext of the View called since another .cs).
Into my view i am using an itemsControl in order to have a button for each element of a observablecollection of a Model. Moreover into my view I have got an ListView. I want that every time a button of the itemsControl is clicked a new line appears into my Lisview.
This last thing is what it does not work!!
Using debug I enter into my command, the command add an object into my observable collection but the app does not actualize the View.

Into my ViewModel, I am using INotifyPropertyChanged, RelayCommand and ICommand.

I let you my code.
Can you help me with my matter ???
thanks:

My View :

<UserControl x:Class="LMarket.Views.CaisseView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
             xmlns:local="clr-namespace:LMarket.Views"
             xmlns:localM="clr-namespace:LMarket.Models"
             xmlns:localModel="clr-namespace:LMarket.ViewModels"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             mc:Ignorable="d">
    <UserControl.Resources>
        <localModel:CaisseViewModel x:Key="CaisseViewModel"/>
        <localM:ProduitDuStock x:Key="ProduitDuStockModel"/>
    </UserControl.Resources>
    <Grid Name="MainGrid">
        <Grid.RowDefinitions>
            <RowDefinition Height="50"/>
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Image Cursor="Hand" Source="/Resources/homepage.png" Width="32" Height="32" HorizontalAlignment="Left" Margin="15,10" Grid.Row="0">

        </Image>
        <Image Cursor="Hand" Source="/Resources/LogOut.png" Width="32" Height="32" HorizontalAlignment="Right" Margin="15,10" Grid.Row="0">

        </Image>
        <Grid Grid.Row="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="1*"/>
            </Grid.ColumnDefinitions>
            <Border Grid.Column="0" BorderThickness="2" BorderBrush="Azure" Margin="5,5,1,5">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="50"/>
                        <RowDefinition Height="1*" />
                        <RowDefinition Height="50" />
                        <RowDefinition Height="50"/>
                    </Grid.RowDefinitions>
                    <Grid Grid.Row="0" Background="#FFC2E0ED">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                            <Image Cursor="Hand" VerticalAlignment="Center"  Width="32" Height="32" Source="/Resources/files-and-folders.png"/>
                            <Image Cursor="Hand" VerticalAlignment="Center" Margin="10,0" Width="32" Height="32" Source="/Resources/cancel.png"/>
                        </StackPanel>
                    </Grid>
                    <ListView Grid.Row="1" Margin="5" SelectionMode="Single"
                              HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding Path=LstProducts, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                        <ListView.ItemTemplate>
                            <DataTemplate DataType="localM:ProduitDuStock">
                                <StackPanel Margin="2" MinWidth="244">
                                    <StackPanel.Resources>
                                         -->
                                        </Style>
                                    </StackPanel.Resources>
                                    <DockPanel >
                                        <TextBlock FontWeight="Bold" Text="Produit: " DockPanel.Dock="Left" Margin="5,0,5,0"/>
                                        <TextBlock Text="  " />
                                        <TextBlock Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="Green" FontWeight="Bold" />
                                    </DockPanel>
                                </StackPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                    <DockPanel Grid.Row="2" Margin="5" Background="#FF296B88">

                    </DockPanel>
                    <Grid Grid.Row="3" Background="#FFC2E0ED">
                        <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="2">
                            <Button Cursor="Hand" Width="80" Content="Cuenta %" Background="#FF98ADA8" BorderBrush="#FF4A6DFF" Margin="2,0">
                                <Button.Resources>

                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="Producto %" Background="#FF98ADA8" BorderBrush="#FF4A6DFF" Margin="2,0">
                                <Button.Resources>

                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="-1" Background="#FFDDCF00" BorderBrush="#FF4A6DFF" FontWeight="Bold" FontSize="20">
                                <Button.Resources>

                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="80" Content="+1" Background="#FF79C837" BorderBrush="#FF4A6DFF" FontWeight="Bold" FontSize="20" Margin="2,0">
                                <Button.Resources>

                                </Button.Resources>
                            </Button>
                            <Button Cursor="Hand" Width="auto" Content="  Validar para Pagar  " Command="{Binding AddNewProductCommand}" Background="#FF98ADA8" BorderBrush="#FF4A6DFF"  FontSize="19" Margin="80,0,2,0" Foreground="Black">
                                <Button.Resources>

                                </Button.Resources>
                            </Button>
                        </StackPanel>
                    </Grid>
                </Grid>
            </Border>
            <Border Grid.Column="1" BorderThickness="2" BorderBrush="Azure" Margin="1,5,5,5">
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="*" MaxHeight="720"/>
                        <RowDefinition Height="1" />
                    </Grid.RowDefinitions>
                    <ScrollViewer Grid.Row="0" Background="Transparent"
                                  HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
                        <ItemsControl ItemsSource="{Binding ListOfProducts}" MaxWidth="762">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel/>
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border Cursor="Hand" CornerRadius="8" Margin="4,3" BorderThickness="1.5" BorderBrush="#FFFDFF00">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FF6F92DC" Offset="1"/>
                                                <GradientStop Color="#FFA6DBFF" Offset="0.534"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <Button BorderBrush="Transparent" Background="Transparent" Command="{Binding Source={StaticResource CaisseViewModel}, Path=AddNewProductCommand}" CommandParameter="{Binding Id}">
                                            <Button.Resources>

                                            </Button.Resources>
                                            <StackPanel Orientation="Vertical" Margin="2" Width="80" Height="80">

                                                <Image Source="{Binding ProductImageUrl}" Width="40" Height="40" Margin="0,10,0,5"
                                                   HorizontalAlignment="Center"/>

                                        </StackPanel>
                                        </Button>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </ScrollViewer>
                </Grid>
            </Border>
        </Grid>
    </Grid>
</UserControl>

And my ViewModel:

using LMarket.Models;
using LMarket.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Xml;

namespace LMarket.ViewModels
{
    class CaisseViewModel : INotifyPropertyChanged
    {
        //Event for INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public void NotifyPropertyChanged([CallerMemberName] string str = "")
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(str));
        }

        #region Attributs
        private ObservableCollection<ProduitDuStock> listOfProducts;
        private ObservableCollection<ProduitDuStock> lstProducts;
        private ProduitDuStock selectedProduct;
        #endregion
        #region Getter/Setter
        public ObservableCollection<ProduitDuStock> ListOfProducts
        {
            get
            {
                return listOfProducts;
            }
            set
            {
                if (listOfProducts != value)
                {
                    listOfProducts = value;
                }
                NotifyPropertyChanged();
            }
        }
        public ObservableCollection<ProduitDuStock> LstProducts
        {
            get
            {
                return lstProducts;
            }
            set
            {
                if (lstProducts != value)
                {
                    lstProducts = value;
                }
                NotifyPropertyChanged();
            }
        }
        public ProduitDuStock SelectedProduct
        {
            get
            {
                return selectedProduct;
            }
            set
            {
                if (selectedProduct != value)
                {
                    selectedProduct = value;
                    NotifyPropertyChanged();
                }
            }
        }

        #endregion

        #region Constructeur
        public CaisseViewModel()
        {
            ListOfProducts = new ObservableCollection<ProduitDuStock>();
            LstProducts = new ObservableCollection<ProduitDuStock>();
            toto();
            //Lecture du fichier ou son enregistrer les données du stock (En local sur un .xml)
            try
            {
                //Ouverture du document XML
                XmlDocument xmlDoc = new XmlDocument();
                string Path = Directory.GetCurrentDirectory().ToString();
                Path = Path + "\\Configuration\\Stockes.xml";
                xmlDoc.Load(Path);
                //Recupérer la section des produits
                XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/Stockes/Products/product");
                //Pour chaque produit dans le fichier, créer un objet ProduitDuStock et l'ajouter à l'ObservableCollection.
                foreach (XmlNode node in nodeList)
                {
                    //Creation du nouvel objet
                    ProduitDuStock testProduit = new ProduitDuStock();
                    foreach (XmlAttribute att in node.Attributes)
                    {
                        //Récupération des parametres de l'objet.
                        switch (att.Name)
                        {
                            case "id":
                                testProduit.Id = int.Parse(att.Value);
                                break;
                            case "name":
                                testProduit.Name = att.Value;
                                break;
                            case "pays":
                                testProduit.Pays = att.Value;
                                break;
                            case "surname":
                                testProduit.Surname = att.Value;
                                break;
                            case "quantite":
                                testProduit.Quantite = int.Parse(att.Value);
                                break;
                            case "unitprice":
                                testProduit.UnitPrice = int.Parse(att.Value);
                                break;
                            case "productImageUrl":
                                testProduit.ProductImageUrl = att.Value;
                                break;
                            default:
                                break;
                        }
                    }
                    //Ajouter l'objet créé a notre ObservableCollection.
                    ListOfProducts.Add(testProduit);
                }

            }
            catch (Exception ex)
            {

            }
        }
        #endregion

        #region Command Definition
        //Event RelayCommand Definition
        private RelayCommand addProductToBill = null;
        public ICommand AddProductToBill
        {
            get
            {
                if (addProductToBill == null)
                {
                    addProductToBill = new RelayCommand(OnAddProductToBill);
                }
                return addProductToBill;
            }
        }
        private RelayCommand addNewProductCommand = null;
        public ICommand AddNewProductCommand
        {
            get
            {
                if (addNewProductCommand == null)
                {
                    addNewProductCommand = new RelayCommand(OnAddNewProductCommand);
                }
                return addNewProductCommand;
            }
        }
        #endregion

        #region Command function definition
        //Event lorsque le curseur rentre dans la zone du boutton "Stock"
        private void OnAddNewProductCommand(object obj)
        {
            toto();
        }

        private void OnAddProductToBill(object obj)
        {
            toto();
        }
        #endregion

        #region function
        public void toto()
        {
            ProduitDuStock myAddProductToBill = new ProduitDuStock();
            myAddProductToBill.Name = "trrt";
            LstProducts.Add(myAddProductToBill);
        }
        #endregion
    }
}

the important part into the view is the next:

<Button BorderBrush="Transparent" Background="Transparent" Command="{Binding Source={StaticResource CaisseViewModel}, Path=AddNewProductCommand}" CommandParameter="{Binding Id}">

remember that this button is defined into a itemsControl ! So the Datacontextof the button is not my viewModel that why I am using a staticResource...

I hope something will help me :) thank you very much.

Body:
Welcome to SO! For future reference, you'll have a much better chance of getting your questions answered if you post an MCVE, there's enough unnecessary code in what you posted to put most people here off.

To answer your question, there are actually many things wrong with this code, but the main issue is that you're creating callback handlers of type RelayCommand, yet your command handler (AddProductToBill) expects an object parameter and should thus be of type RelayCommand<object>. (More confusingly, one of your bindings is passing in CommandParameter, while the other is not).

Another thing to avoid is declaring your view model in your resources block, this is generally not done for a variety of reasons (are you sure you're assigning that instance as your DataContext and not declaring a new one?). If you're assigning your DataContext elsewhere then your list elements can bind to it with something like this:

<UserControl ...
    x:Name="_this">
    .
    .
    <!-- Inside ItemsControl.ItemTemplate -->
    <Button
        Command="{Binding ElementName=_this, Path=DataContext.MyHandler}"
        CommandParameter="{Binding}" ... />


问:
Dataframe Groupby to combine multiple rows, summing float-type columns
Terrible title, but Here goes.  I have a 13,000 x 91 dataframe.  26 of the columns are numeric.  The rows are individual projects, with project performance split by year.  Like this:

```<code>| Year | Control | Description   | USD_Cost | USD_Profit |
|------|---------|---------------|----------|------------|
| 1991 | A1      | A description | 1        | 2          |
| 1992 | A1      | A Description | 100      | 300        |
| 1991 | B1      | B Description | 3        | 50         |
| 1995 | C1      | C Description | 5        | 10         |
| 1990 | D1      | D Description | 2        | 1          |
| 1996 | D1      | D Description | 1        | 1          |
</code>```

Rather than recording how each project performed in each particular year, I just want to record how long each project lasted, and the overall project performance:

```<code>| Years | Control | Description   | USD_Cost | USDProfit |
|-------|---------|---------------|----------|-----------|
| 2     | A1      | A description | 101      | 302       |
| 1     | B1      | B Description | 3        | 50        |
| 1     | C1      | C Description | 5        | 10        |
| 2     | D1      | D Description | 3        | 2         |
</code>```

Control and Description aren't changed, but the numeric columns beginning with USD are summed across rows.  And there are 26 USD columns for different performance aspects. There are about 8000 unique Control Numbers but 13000 total Year-ControlNumber combos.

I know how to groupby for one element (e.g. print(dft.groupby(['Control'])['USD_Cost', 'USD_Profit'].sum() ) but when I do that, I think I am losing all the non-numeric columns.  Also, I would like to avoid typing in the names of all 26 USD columns.

Can this be done with groupby?

答:
I think this should work for you

columns = list(filter(lambda x: 'USD' in x, df.columns))

df.groupby(['Control', 'Description'])[columns].sum()

That would bring you all columns grouped by Control, Description. This wouldn't be a problem for what you're up to, so I think this would be the best way.

Body:
Terrible title, but Here goes.  I have a 13,000 x 91 dataframe.  26 of the columns are numeric.  The rows are individual projects, with project performance split by year.  Like this:

| Year | Control | Description   | USD_Cost | USD_Profit |
|------|---------|---------------|----------|------------|
| 1991 | A1      | A description | 1        | 2          |
| 1992 | A1      | A Description | 100      | 300        |
| 1991 | B1      | B Description | 3        | 50         |
| 1995 | C1      | C Description | 5        | 10         |
| 1990 | D1      | D Description | 2        | 1          |
| 1996 | D1      | D Description | 1        | 1          |

Rather than recording how each project performed in each particular year, I just want to record how long each project lasted, and the overall project performance:

| Years | Control | Description   | USD_Cost | USDProfit |
|-------|---------|---------------|----------|-----------|
| 2     | A1      | A description | 101      | 302       |
| 1     | B1      | B Description | 3        | 50        |
| 1     | C1      | C Description | 5        | 10        |
| 2     | D1      | D Description | 3        | 2         |

Control and Description aren't changed, but the numeric columns beginning with USD are summed across rows.  And there are 26 USD columns for different performance aspects. There are about 8000 unique Control Numbers but 13000 total Year-ControlNumber combos.

I know how to groupby for one element (e.g. print(dft.groupby(['Control'])['USD_Cost', 'USD_Profit'].sum() ) but when I do that, I think I am losing all the non-numeric columns.  Also, I would like to avoid typing in the names of all 26 USD columns.

Can this be done with groupby?


问:
biopython no module named Bio
FYI: this is NOT a duplicate!

Before running my python code I installed biopython in the cmd prompt:

```<code>pip install biopython
</code>```

I then get an error saying 'No module named Bio' when try to import it in python

```<code>import Bio
</code>```

The same thing happens with

```<code>import biopython
</code>```

It should be noted I have updated PIP and run python 3.5.2

 I appreciate anyone's help.

答:
In my case (MacOS X Catalina, python 3.7.6 installed by brew), I had to install it with

```<code>python -m pip install Bio
</code>```

(uppercase) but use it with

```<code>from bio import pairwise2
</code>```

and the worse is that I had to change the code of the package: I went into python3.7/site-packages/bio/pairwise2.py, line 246, changed

```<code>from Bio import BiopythonWarning
</code>```

into

```<code>from bio import BiopythonWarning
</code>```

I hate changing the code of the package, on the next update it won't work again… Please do something to fix this bio/Bio issue.

Title: biopython no module named Bio

Body:
FYI: this is NOT a duplicate!

Before running my python code I installed biopython in the cmd prompt:

pip install biopython

I then get an error saying 'No module named Bio' when try to import it in python

import Bio

The same thing happens with

import biopython

It should be noted I have updated PIP and run python 3.5.2

 I appreciate anyone's help.

Body:
In my case (MacOS X Catalina, python 3.7.6 installed by brew), I had to install it with

python -m pip install Bio

(uppercase) but use it with

from bio import pairwise2

and the worse is that I had to change the code of the package: I went into python3.7/site-packages/bio/pairwise2.py, line 246, changed

from Bio import BiopythonWarning

into

from bio import BiopythonWarning

I hate changing the code of the package, on the next update it won't work again… Please do something to fix this bio/Bio issue.


问:
Cannot find the symmetric key '', because it does not exist or you do not have permission
Using SQL 2005

I created a Master Key encrypted by password and then encrypted the Master Key with the Service Master Key

I then created an ASYMMETRIC_KEY which I use to encrypt my SYMMETRIC_KEY I did all this using the SA user for SQL and logged into windows server as the domain admin.

I have a user in my database that only has dbo permissions on my database and then I grant that user execute permissions on all the necessary stored procedures and I also deny view definition to those same stored procedures.

The stored procedure giving me trouble where I do the encryption is this here. Also this all worked on SQL2012 in my testing pc but now that I am creating this on production server with sql 2005 and it is failing

```<code>open symmetric key
    MYKEY_NAME_SYM decryption by Asymmetric key MYKEY_NAME_ASYM
    set @ENCRYPTVARIABLE = (select ENCRYPTBYKEY(KEY_GUID('MYKEY_NAME_SYM'), @ENCRYPTCOLUMN))
close symmetric key MYKEY_NAME_SYM
</code>```

The error I am receiving is:

```<code>Cannot find the symmetric key 'MKEY_NAME_SYM', because it does not exist or you do not have permission.
</code>```

So I am guessing that the user I am using in my database does not have permissions but when I try to grant permissions

```<code>GRANT
VIEW DEFINITION ON SYMMETRIC KEY::MKEY_NAME_SYM TO [myuser]
</code>```

I get the same error cannot find the symmetric key or I don't have permissions.

答:
One thing I haven't seen others mention: To create a login from a symmetric or asymmetric key, the key and the login must both be created in the MASTER database.

Example:

```<code>USE MASTER
IF NOT EXISTS (SELECT 1 FROM sys.asymmetric_keys where name = 'MySecret.AsymmetricKey') BEGIN
    CREATE ASYMMETRIC KEY [AsymmetricKey]
    FROM FILE='C:\temp\MyStrongNameKey.snk'
END

IF NOT EXISTS (SELECT 1 from sys.sql_logins where name = 'StrongNameKeyLogin') BEGIN
    CREATE LOGIN [StrongNameKeyLogin]
    FROM ASYMMETRIC KEY [AsymmetricKey]
END
GO

-- If necessary, do this here:
GRANT UNSAFE ASSEMBLY TO [StrongNameKeyLogin]

USE [MyDatabase]
-- Now you can create assemblies, or do whatever else you need that references the signed login
</code>```

Body:
Using SQL 2005

I created a Master Key encrypted by password and then encrypted the Master Key with the Service Master Key

I then created an ASYMMETRIC_KEY which I use to encrypt my SYMMETRIC_KEY I did all this using the SA user for SQL and logged into windows server as the domain admin.

I have a user in my database that only has dbo permissions on my database and then I grant that user execute permissions on all the necessary stored procedures and I also deny view definition to those same stored procedures.

The stored procedure giving me trouble where I do the encryption is this here. Also this all worked on SQL2012 in my testing pc but now that I am creating this on production server with sql 2005 and it is failing

open symmetric key
    MYKEY_NAME_SYM decryption by Asymmetric key MYKEY_NAME_ASYM
    set @ENCRYPTVARIABLE = (select ENCRYPTBYKEY(KEY_GUID('MYKEY_NAME_SYM'), @ENCRYPTCOLUMN))
close symmetric key MYKEY_NAME_SYM

The error I am receiving is:

Cannot find the symmetric key 'MKEY_NAME_SYM', because it does not exist or you do not have permission.

So I am guessing that the user I am using in my database does not have permissions but when I try to grant permissions

GRANT
VIEW DEFINITION ON SYMMETRIC KEY::MKEY_NAME_SYM TO [myuser]

I get the same error cannot find the symmetric key or I don't have permissions.

Body:
One thing I haven't seen others mention: To create a login from a symmetric or asymmetric key, the key and the login must both be created in the MASTER database.

Example:

USE MASTER
IF NOT EXISTS (SELECT 1 FROM sys.asymmetric_keys where name = 'MySecret.AsymmetricKey') BEGIN
    CREATE ASYMMETRIC KEY [AsymmetricKey]
    FROM FILE='C:\temp\MyStrongNameKey.snk'
END

IF NOT EXISTS (SELECT 1 from sys.sql_logins where name = 'StrongNameKeyLogin') BEGIN
    CREATE LOGIN [StrongNameKeyLogin]
    FROM ASYMMETRIC KEY [AsymmetricKey]
END
GO

-- If necessary, do this here:
GRANT UNSAFE ASSEMBLY TO [StrongNameKeyLogin]

USE [MyDatabase]
-- Now you can create assemblies, or do whatever else you need that references the signed login


问:
WPF Calendar Control holding on to the Mouse
So I dropped the standard WPF Calendar control on the MainWindow.xaml in a brand new WPF App in VS2010.  If I click on a day in the calendar and then try to click the Close button for the app, I have to click twice on the close button before it accepts the click.  It's acting as if the Calendar hasn't released the Mouse to interact with the rest of the application.

I've changed Focusable to false, with no change in effect, and I've tried overriding the PreviewOnMouseUp and calling ReleaseMouseCapture() to no avail.  I've done the same thing with MouseLeave and MouseLeftButtonUp with the same result.  Given that none of those things are working I suspect I'm barking up the wrong tree.  Google has turned up nothing of note, though perhaps my GoogleFu is not up to snuff today.

Any ideas?

答:
The calendar control is hosted in a popup, and captures the mouse.  When you click somewhere else the first time, the capture sends the click to the popup, which, realizing that you've clicked outside of itself, closes.  The click therefore does not go to the button.

You can see the same effect when using a ComboBox.  Drop it down, then click on a button.  It won't click the button.

Unfortunately, it's unlikely you can do anything to alter this behavior.

Edit: More recent versions of .NET make a solution possible.  See Eren's answer.


问:
Corda - Failed to find a store at certificates\sslkeystore.jks
Corda open source on Linux. Node RPC SSL enabled. I am getting error "Failed to find a store at certificates\sslkeystore.jks". Any ideas? I have entered absolute path in keyStorePath.</p>

答:
You must follow the steps of this paragraph: https://docs.corda.net/clientrpc.html#wire-security which I detailed for you below.

When you enable RPC SSL, you must run this command one time (you will be asked to supply 2 new passwords):

```<code>java -jar corda.jar generate-rpc-ssl-settings
</code>```

It will create the rpcsslkeystore.jks under certificates folder, and rpcssltruststore.jks under certificates/export folder.

Inside your node.conf supply the path and password of rpcsslkeystore.jks:

```<code>rpcSettings {
    useSsl=true
    ssl {
       keyStorePath=${baseDirectory}/certificates/rpcsslkeystore.jks
       keyStorePassword=password
    }
    standAloneBroker = false
    address = "0.0.0.0:10003"
    adminAddress = "0.0.0.0:10004"
}

</code>```

Now if you have a webserver, inside NodeRPCConnection you must use the constructor that takes a ClientRpcSslOptions parameter:

```<code>// RPC SSL properties.
@Value("${config.rpc.ssl.truststorepath}")
private String trustStorePath;
@Value("${config.rpc.ssl.truststorepassword}")
private String trustStorePassword;

@PostConstruct
public void initialiseNodeRPCConnection() {
    NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, rpcPort);
    ClientRpcSslOptions clientRpcSslOptions = new ClientRpcSslOptions(Paths.get(trustStorePath),
            trustStorePassword, "JKS");
    CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress, clientRpcSslOptions, null);
    rpcConnection = rpcClient.start(username, password);
    proxy = rpcConnection.getProxy();
}
</code>```

We added above 2 extra attributes that you must now supply when starting the webserver, for that; modify your clients module build.gradle:

```<code>task runNodeServer(type: JavaExec, dependsOn: jar) {
    classpath = sourceSets.main.runtimeClasspath
    main = 'com.example.server.ServerKt'
    args '--server.port=50005', '--config.rpc.host=localhost',
    '--config.rpc.port=10005', '--config.rpc.username=user1', '--config.rpc.password=test',
    '--config.rpc.ssl.truststorepath=/path-to-project/build/nodes/your-node/certificates/export/rpcssltruststore.jks',
    '--config.rpc.ssl.truststorepassword=password'
}
</code>```

If you're planning to connect to the node with a standalone shell, you must do something similar, but it didn't work for me; I reported the following bug: https://github.com/corda/corda/issues/5955

Body:
You must follow the steps of this paragraph: https://docs.corda.net/clientrpc.html#wire-security which I detailed for you below.

When you enable RPC SSL, you must run this command one time (you will be asked to supply 2 new passwords):

java -jar corda.jar generate-rpc-ssl-settings

It will create the rpcsslkeystore.jks under certificates folder, and rpcssltruststore.jks under certificates/export folder.

Inside your node.conf supply the path and password of rpcsslkeystore.jks:

rpcSettings {
    useSsl=true
    ssl {
       keyStorePath=${baseDirectory}/certificates/rpcsslkeystore.jks
       keyStorePassword=password
    }
    standAloneBroker = false
    address = "0.0.0.0:10003"
    adminAddress = "0.0.0.0:10004"
}

Now if you have a webserver, inside NodeRPCConnection you must use the constructor that takes a ClientRpcSslOptions parameter:

// RPC SSL properties.
@Value("${config.rpc.ssl.truststorepath}")
private String trustStorePath;
@Value("${config.rpc.ssl.truststorepassword}")
private String trustStorePassword;

@PostConstruct
public void initialiseNodeRPCConnection() {
    NetworkHostAndPort rpcAddress = new NetworkHostAndPort(host, rpcPort);
    ClientRpcSslOptions clientRpcSslOptions = new ClientRpcSslOptions(Paths.get(trustStorePath),
            trustStorePassword, "JKS");
    CordaRPCClient rpcClient = new CordaRPCClient(rpcAddress, clientRpcSslOptions, null);
    rpcConnection = rpcClient.start(username, password);
    proxy = rpcConnection.getProxy();
}

We added above 2 extra attributes that you must now supply when starting the webserver, for that; modify your clients module build.gradle:

task runNodeServer(type: JavaExec, dependsOn: jar) {
    classpath = sourceSets.main.runtimeClasspath
    main = 'com.example.server.ServerKt'
    args '--server.port=50005', '--config.rpc.host=localhost',
    '--config.rpc.port=10005', '--config.rpc.username=user1', '--config.rpc.password=test',
    '--config.rpc.ssl.truststorepath=/path-to-project/build/nodes/your-node/certificates/export/rpcssltruststore.jks',
    '--config.rpc.ssl.truststorepassword=password'
}

If you're planning to connect to the node with a standalone shell, you must do something similar, but it didn't work for me; I reported the following bug: https://github.com/corda/corda/issues/5955


答:
Try:

```<code>$string = 'abc87#@-';
echo preg_replace('/^([a-zA-Z0-9]*).*$/', '$1', $string);
</code>```

Prints:

```<code>abc87
</code>```

The idea is that in scanning the string abc87#@-, abc87 becomes capture group 1 and #@- is everything else (i.e. .*). Thus the regex matches the entire string and you therefore replacing the entire string with just capture group 1.

Title: Regex to remove everything BEFORE and AFTER letter or numbers on a string

Body:
I'm making a function using PHP to clean a name string.

So, I have names like these:

$name_1 = ' \'Brian    O\'Ril"*ley';
$name_2 = ' \'   " José Sant\'Anna';

# Output expected:
# Brian O'Rilley
# José Sant'Anna

My function code:

function cleanName($string)
{
  # --------------------------------------------------
  # Remove everything before first letter and after last letter
  # --------------------------------------------------
  $string = preg_replace('/^[^A-Za-z0-9]+/','',$string);
  # --------------------------------------------------
  # Clean spaces
  # --------------------------------------------------
  $string = htmlentities($string,null,'utf-8');
  $string = str_replace(' ',' ',$string);
  $string = preg_replace('!\s+!',' ',$string);
  $string = html_entity_decode($string);
  # --------------------------------------------------
  # Replace quotes
  # --------------------------------------------------
  $string = str_replace(array('`','´','´´','``','"'),'\'',$string);
  $string = preg_replace("/'{2,}/","'",$string);
  # --------------------------------------------------
  # Remove everything but letters, single spaces, simple quotes, and ISO-8859-1 characters
  # --------------------------------------------------
  $string = preg_replace('/[^A-Za-z0-9 \'\xC0-\xD6\xD8-\xF6\xF8-\xFF]+/u','',$string);
  # --------------------------------------------------
  # Upper case on fisrt letters
  # --------------------------------------------------
  $string = ucwords(strtolower($string));
  # --------------------------------------------------
  # Output
  # --------------------------------------------------
  return $string;
}

The code does pretty much everything I need, BUT:

# This one only removes BEFORE - I also need to remove AFTER
$string = preg_replace('/^[^A-Za-z0-9]+/','',$string);

I'm really struggling to find a way to remove anything after the last letter/number.

Can someone help me with that?
If the before and after it's on a single regex, even better.
Any other suggestion to make my code better is welcome!

Thanks

Body:
Try:

$string = 'abc87#@-';
echo preg_replace('/^([a-zA-Z0-9]*).*$/', '$1', $string);

Prints:

abc87

The idea is that in scanning the string abc87#@-, abc87 becomes capture group 1 and #@- is everything else (i.e. .*). Thus the regex matches the entire string and you therefore replacing the entire string with just capture group 1.


问:
Powershell: how to split, do math and format
I am looking for a 1-liner that looks something like this:

(gitversion | ConvertFrom-Json).SemVer.split('.') | [string]::Format("{0}.{1}.{2}",$_[0],$_[1] + 1,$_[2]) | git tag $_
```

So, right now I have 0.1.0 and I want a 1 liner that will map it to:
0.2.0

I am sure a guru in PS can make fast work of this

答:
Note: The solutions below assume that a string representation such as 0.1.0 is to be parsed; as it turns out, the JSON that utility gitversion outputs has individual version-number components such as Major, Minor, ..., which Jawad's answer relies on; however, even utilizing the individual properties for synthesizing an output string can be challenging, if all semver version components are to be preserved.

For a solution that is both robust and convenient, use the [semver] (System.Management.Automation.SemanticVersion) type that PowerShell [Core] 6+ offers (command is spread across multiple lines for readability):

You can simply cast a version string such as 0.1.0 to [semver], yielding an object with numeric .Major, .Minor, and .Patch properties, alongside others; you can construct a new [semver] instance from it, with the modified minor version and all other properties passed through:

```<code>(gitversion | ConvertFrom-Json).FullSemVer | foreach {
   $v = [semver] $_;
   [semver]::new($v.Major, ($v.Minor+1), $v.Patch, $v.PreReleaseLabel, $v.BuildLabel)
  } | foreach {
        git tag $_
      }
</code>```

foreach is the built-in alias for the  ForEach-Object cmdlet.

What the first foreach command outputs is a [semver] object, not a string, but passing such an object implicitly stringifies it, which yields the desired representation.

The above ensures that all components of a semver-compliant version string are preserved on output, notably including the pre-release and build-metadata fields, if present (e.g.,

1.0.0-alpha+001).

If your version-number strings are always composed of 2 - 4 numeric-only components (e.g., 1.0, 1.0.2, 1.0.2.10), you can use the [version] type (System.Version) instead, which is also available in Windows PowerShell (PowerShell versions 5.1 and below):

```<code>'0.1.0.34' | foreach {
    $v = [version] $_; $newMinor = $v.Minor + 1
    if ($v.Build -ne -1 -and $v.Revision -ne -1) { [version]::new($v.Major, $newMinor, $v.Build, $v.Revision) }
    elseif ($v.Build -ne -1) { [version]::new($v.Major, $newMinor, $v.Build) }
    else {[version]::new($v.Major, $newMinor) }
   } | foreach {
        git tag $_
      }
</code>```

Note the - unfortunate - need to use [version]'s various constructor overloads selectively, which is the consequence of a design asymmetry: non-specified version components (for the optional build and revision fields) default to placeholder -1, but passing these placeholders to the 4-component constructor is not supported.

Note: The advantage of the above solutions is that you get proper object representations of the version numbers, which make programmatic processing easier in general.

However, it is baffling that neither [semver] nor [version]
themselves offer methods for incrementing the version numbers they represent.

If all you need is the string representation of the modified version number,
a concise regex-based based text-parsing solution is possible too, which again PowerShell [Core] 6.2+ makes easier, because the regex-based -replace operator there supports script-block-based substitutions (see the linked answer for how to do it in Windows PowerShell):

```<code>(gitversion | ConvertFrom-Json).FullSemVer | foreach {
   $_ -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
  } | foreach {
        git tag $_
      }
</code>```

Variations of the regex for incrementing the 3 version-number components  (trailing pre-release and build labels would be preserved):

the major number (e.g., 2.0.9 -> 3.0.9):

'2.0.9' -replace '\d+(?=\..+)', { 1 + [int] $_.Value }

the minor number (as above; 2.0.9 -> 2.1.9)):

'2.0.9' -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }

the patch number (third component; 2.0.9 -> 2.0.10):

'2.0.9' -replace '(?<=^\d+\.\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }

Caveat: The assumption is that the targeted version component is present in the input string; e.g., trying to increment the patch component in input string '2.0' would not work; this fragility is another reason to prefer an object-based approach via [semver].

Body:
I am looking for a 1-liner that looks something like this:

(gitversion | ConvertFrom-Json).SemVer.split('.') | [string]::Format("{0}.{1}.{2}",$_[0],$_[1] + 1,$_[2]) | git tag $_

So, right now I have 0.1.0 and I want a 1 liner that will map it to:
0.2.0

I am sure a guru in PS can make fast work of this

Body:
Note: The solutions below assume that a string representation such as 0.1.0 is to be parsed; as it turns out, the JSON that utility gitversion outputs has individual version-number components such as Major, Minor, ..., which Jawad's answer relies on; however, even utilizing the individual properties for synthesizing an output string can be challenging, if all semver version components are to be preserved.

For a solution that is both robust and convenient, use the [semver] (System.Management.Automation.SemanticVersion) type that PowerShell [Core] 6+ offers (command is spread across multiple lines for readability):

You can simply cast a version string such as 0.1.0 to [semver], yielding an object with numeric .Major, .Minor, and .Patch properties, alongside others; you can construct a new [semver] instance from it, with the modified minor version and all other properties passed through:

(gitversion | ConvertFrom-Json).FullSemVer | foreach {
   $v = [semver] $_;
   [semver]::new($v.Major, ($v.Minor+1), $v.Patch, $v.PreReleaseLabel, $v.BuildLabel)
  } | foreach {
        git tag $_
      }

foreach is the built-in alias for the  ForEach-Object cmdlet.

What the first foreach command outputs is a [semver] object, not a string, but passing such an object implicitly stringifies it, which yields the desired representation.

The above ensures that all components of a semver-compliant version string are preserved on output, notably including the pre-release and build-metadata fields, if present (e.g.,

1.0.0-alpha+001).

If your version-number strings are always composed of 2 - 4 numeric-only components (e.g., 1.0, 1.0.2, 1.0.2.10), you can use the [version] type (System.Version) instead, which is also available in Windows PowerShell (PowerShell versions 5.1 and below):

'0.1.0.34' | foreach {
    $v = [version] $_; $newMinor = $v.Minor + 1
    if ($v.Build -ne -1 -and $v.Revision -ne -1) { [version]::new($v.Major, $newMinor, $v.Build, $v.Revision) }
    elseif ($v.Build -ne -1) { [version]::new($v.Major, $newMinor, $v.Build) }
    else {[version]::new($v.Major, $newMinor) }
   } | foreach {
        git tag $_
      }

Note the - unfortunate - need to use [version]'s various constructor overloads selectively, which is the consequence of a design asymmetry: non-specified version components (for the optional build and revision fields) default to placeholder -1, but passing these placeholders to the 4-component constructor is not supported.

Note: The advantage of the above solutions is that you get proper object representations of the version numbers, which make programmatic processing easier in general.

However, it is baffling that neither [semver] nor [version]
themselves offer methods for incrementing the version numbers they represent.

If all you need is the string representation of the modified version number,
a concise regex-based based text-parsing solution is possible too, which again PowerShell [Core] 6.2+ makes easier, because the regex-based -replace operator there supports script-block-based substitutions (see the linked answer for how to do it in Windows PowerShell):

(gitversion | ConvertFrom-Json).FullSemVer | foreach {
   $_ -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }
  } | foreach {
        git tag $_
      }

Variations of the regex for incrementing the 3 version-number components  (trailing pre-release and build labels would be preserved):

the major number (e.g., 2.0.9 -> 3.0.9):

'2.0.9' -replace '\d+(?=\..+)', { 1 + [int] $_.Value }

the minor number (as above; 2.0.9 -> 2.1.9)):

'2.0.9' -replace '(?<=^\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }

the patch number (third component; 2.0.9 -> 2.0.10):

'2.0.9' -replace '(?<=^\d+\.\d+\.)\d+(?=.*)', { 1 + [int] $_.Value }

Caveat: The assumption is that the targeted version component is present in the input string; e.g., trying to increment the patch component in input string '2.0' would not work; this fragility is another reason to prefer an object-based approach via [semver].


问:
Have the parent execute something while waiting for child
I am trying to have two things execute at the same time. I have some code to run a PWM module, and I have some code to read from an ADC and both work. I want to now read from the ADC while waiting for the pwm module to finish. I thought of forking, but wasn't sure how to get the parent to wait for the child to finish.

I'd like to have something like the following:

```<code>pid = os.fork()
if(pid > 0):
     while(child not done):
         adc code
else:
    pwm code
</code>```

答: You can use os.wait() from the parent process to wait for the child to terminate. You can find an example of this here.

Body:
I am trying to have two things execute at the same time. I have some code to run a PWM module, and I have some code to read from an ADC and both work. I want to now read from the ADC while waiting for the pwm module to finish. I thought of forking, but wasn't sure how to get the parent to wait for the child to finish.

I'd like to have something like the following:

pid = os.fork()
if(pid > 0):
     while(child not done):
         adc code
else:
    pwm code


问:
How can I specify a placeholder image?
I am using Google's ImageDownloader as seen in their multithreading for performance blog article: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

I want to be able to specify a default placeholder image while images are downloaded off the internet. How can I do this?

Here is the code:

```<code>/**
 * This helper class download images from the Internet and binds those with the provided ImageView.
 *
 * <p>It requires the INTERNET permission, which should be added to your application's manifest
 * file.</p>
 *
 * A local cache of downloaded images is maintained internally to improve performance.
 */
public class ImageDownloader {
    private static final String LOG_TAG = "ImageDownloader";

    public enum Mode { NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT }
    private Mode mode = Mode.CORRECT;   //Mode.NO_ASYNC_TASK;

    /**
     * Download the specified image from the Internet and binds it to the provided ImageView. The
     * binding is immediate if the image is found in the cache and will be done asynchronously
     * otherwise. A null bitmap will be associated to the ImageView if an error occurs.
     *
     * @param url The URL of the image to download.
     * @param imageView The ImageView to bind the downloaded image to.
     */
    public void download(String url, ImageView imageView) {
        resetPurgeTimer();
        Bitmap bitmap = getBitmapFromCache(url);

        if (bitmap == null) {
            forceDownload(url, imageView);
        } else {
            cancelPotentialDownload(url, imageView);
            imageView.setImageBitmap(bitmap);
        }
    }

    /*
     * Same as download but the image is always downloaded and the cache is not used.
     * Kept private at the moment as its interest is not clear.
       private void forceDownload(String url, ImageView view) {
          forceDownload(url, view, null);
       }
     */

    /**
     * Same as download but the image is always downloaded and the cache is not used.
     * Kept private at the moment as its interest is not clear.
     */
    private void forceDownload(String url, ImageView imageView) {
        // State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys.
        if (url == null) {
            imageView.setImageDrawable(null);
            return;
        }

        if (cancelPotentialDownload(url, imageView)) {
            switch (mode) {
                case NO_ASYNC_TASK:
                    Bitmap bitmap = downloadBitmap(url);
                    addBitmapToCache(url, bitmap);
                    imageView.setImageBitmap(bitmap);
                    break;

                case NO_DOWNLOADED_DRAWABLE:
                    imageView.setMinimumHeight(156);
                    BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
                    task.execute(url);
                    break;

                case CORRECT:
                    task = new BitmapDownloaderTask(imageView);
                    DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
                    imageView.setImageDrawable(downloadedDrawable);
                    imageView.setMinimumHeight(156);
                    task.execute(url);
                    break;
            }
        }
    }

    /**
     * Returns true if the current download has been canceled or if there was no download in
     * progress on this image view.
     * Returns false if the download in progress deals with the same url. The download is not
     * stopped in that case.
     */
    private static boolean cancelPotentialDownload(String url, ImageView imageView) {
        BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);

        if (bitmapDownloaderTask != null) {
            String bitmapUrl = bitmapDownloaderTask.url;
            if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
                bitmapDownloaderTask.cancel(true);
            } else {
                // The same URL is already being downloaded.
                return false;
            }
        }
        return true;
    }

    /**
     * @param imageView Any imageView
     * @return Retrieve the currently active download task (if any) associated with this imageView.
     * null if there is no such task.
     */
    private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
        if (imageView != null) {
            Drawable drawable = imageView.getDrawable();
            if (drawable instanceof DownloadedDrawable) {
                DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
                return downloadedDrawable.getBitmapDownloaderTask();
            }
        }
        return null;
    }

    Bitmap downloadBitmap(String url) {
        //final int IO_BUFFER_SIZE = 4 * 1024;

        // AndroidHttpClient is not allowed to be used from the main thread
        final HttpClient client = (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() :
            AndroidHttpClient.newInstance("Android");
        final HttpGet getRequest = new HttpGet(url);

        try {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                Log.w("ImageDownloader", "Error " + statusCode +
                        " while retrieving bitmap from " + url);
                return null;
            }

            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    inputStream = entity.getContent();
                    // return BitmapFactory.decodeStream(inputStream);
                    // Bug on slow connections, fixed in future release.
                    return BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        } catch (IOException e) {
            getRequest.abort();
            Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
        } catch (IllegalStateException e) {
            getRequest.abort();
            Log.w(LOG_TAG, "Incorrect URL: " + url);
        } catch (Exception e) {
            getRequest.abort();
            Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
        } finally {
            if ((client instanceof AndroidHttpClient)) {
                ((AndroidHttpClient) client).close();
            }
        }
        return null;
    }

    /*
     * An InputStream that skips the exact number of bytes provided, unless it reaches EOF.
     */
    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

    /**
     * The actual AsyncTask that will asynchronously download the image.
     */
    class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
        private String url;
        private final WeakReference<ImageView> imageViewReference;

        public BitmapDownloaderTask(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        /**
         * Actual download method.
         */
        @Override
        protected Bitmap doInBackground(String... params) {
            url = params[0];
            return downloadBitmap(url);
        }

        /**
         * Once the image is downloaded, associates it to the imageView
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }

            addBitmapToCache(url, bitmap);

            if (imageViewReference != null) {
                ImageView imageView = imageViewReference.get();
                BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
                // Change bitmap only if this process is still associated with it
                // Or if we don't use any bitmap to task association (NO_DOWNLOADED_DRAWABLE mode)
                if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }
    }

    /**
     * A fake Drawable that will be attached to the imageView while the download is in progress.
     *
     * <p>Contains a reference to the actual download task, so that a download task can be stopped
     * if a new binding is required, and makes sure that only the last started download process can
     * bind its result, independently of the download finish order.</p>
     */
    static class DownloadedDrawable extends ColorDrawable {
        private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

        public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
            super(Color.BLACK);
            bitmapDownloaderTaskReference =
                new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
        }

        public BitmapDownloaderTask getBitmapDownloaderTask() {
            return bitmapDownloaderTaskReference.get();
        }
    }

    public void setMode(Mode mode) {
        this.mode = mode;
        clearCache();
    }

    /*
     * Cache-related fields and methods.
     *
     * We use a hard and a soft cache. A soft reference cache is too aggressively cleared by the
     * Garbage Collector.
     */

    private static final int HARD_CACHE_CAPACITY = 10;
    private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds

    // Hard cache, with a fixed maximum capacity and a life duration
    private final HashMap<String, Bitmap> sHardBitmapCache =
        new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
        /**
             *
             */
            private static final long serialVersionUID = 1L;

        @Override
        protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
            if (size() > HARD_CACHE_CAPACITY) {
                // Entries push-out of hard reference cache are transferred to soft reference cache
                sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
                return true;
            } else
                return false;
        }
    };

    // Soft cache for bitmaps kicked out of hard cache
    private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
        new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);

    private final Handler purgeHandler = new Handler();

    private final Runnable purger = new Runnable() {
        public void run() {
            clearCache();
        }
    };

    /**
     * Adds this bitmap to the cache.
     * @param bitmap The newly downloaded bitmap.
     */
    private void addBitmapToCache(String url, Bitmap bitmap) {
        if (bitmap != null) {
            synchronized (sHardBitmapCache) {
                sHardBitmapCache.put(url, bitmap);
            }
        }
    }

    /**
     * @param url The URL of the image that will be retrieved from the cache.
     * @return The cached bitmap or null if it was not found.
     */
    public Bitmap getBitmapFromCache(String url) {
        // First try the hard reference cache
        synchronized (sHardBitmapCache) {
            final Bitmap bitmap = sHardBitmapCache.get(url);
            if (bitmap != null) {
                // Bitmap found in hard cache
                // Move element to first position, so that it is removed last
                sHardBitmapCache.remove(url);
                sHardBitmapCache.put(url, bitmap);
                return bitmap;
            }
        }

        // Then try the soft reference cache
        SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
        if (bitmapReference != null) {
            final Bitmap bitmap = bitmapReference.get();
            if (bitmap != null) {
                // Bitmap found in soft cache
                return bitmap;
            } else {
                // Soft reference has been Garbage Collected
                sSoftBitmapCache.remove(url);
            }
        }

        return null;
    }

    /**
     * Clears the image cache used internally to improve performance. Note that for memory
     * efficiency reasons, the cache will automatically be cleared after a certain inactivity delay.
     */
    public void clearCache() {
        sHardBitmapCache.clear();
        sSoftBitmapCache.clear();
    }

    /**
     * Allow a new delay before the automatic cache clear is done.
     */
    private void resetPurgeTimer() {
        purgeHandler.removeCallbacks(purger);
        purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
    }
}
</code>```

答: Set the ImageView to the placeholder in download() before calling forceDownload().

Title: How can I specify a placeholder image?

Body:
I am using Google's ImageDownloader as seen in their multithreading for performance blog article: http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html

I want to be able to specify a default placeholder image while images are downloaded off the internet. How can I do this?

Here is the code:

/**
 * This helper class download images from the Internet and binds those with the provided ImageView.
 *
 *
It requires the INTERNET permission, which should be added to your application's manifest
 * file.

 *
 * A local cache of downloaded images is maintained internally to improve performance.
 */
public class ImageDownloader {
    private static final String LOG_TAG = "ImageDownloader";

    public enum Mode { NO_ASYNC_TASK, NO_DOWNLOADED_DRAWABLE, CORRECT }
    private Mode mode = Mode.CORRECT;   //Mode.NO_ASYNC_TASK;

    /**
     * Download the specified image from the Internet and binds it to the provided ImageView. The
     * binding is immediate if the image is found in the cache and will be done asynchronously
     * otherwise. A null bitmap will be associated to the ImageView if an error occurs.
     *
     * @param url The URL of the image to download.
     * @param imageView The ImageView to bind the downloaded image to.
     */
    public void download(String url, ImageView imageView) {
        resetPurgeTimer();
        Bitmap bitmap = getBitmapFromCache(url);

        if (bitmap == null) {
            forceDownload(url, imageView);
        } else {
            cancelPotentialDownload(url, imageView);
            imageView.setImageBitmap(bitmap);
        }
    }

    /*
     * Same as download but the image is always downloaded and the cache is not used.
     * Kept private at the moment as its interest is not clear.
       private void forceDownload(String url, ImageView view) {
          forceDownload(url, view, null);
       }
     */

    /**
     * Same as download but the image is always downloaded and the cache is not used.
     * Kept private at the moment as its interest is not clear.
     */
    private void forceDownload(String url, ImageView imageView) {
        // State sanity: url is guaranteed to never be null in DownloadedDrawable and cache keys.
        if (url == null) {
            imageView.setImageDrawable(null);
            return;
        }

        if (cancelPotentialDownload(url, imageView)) {
            switch (mode) {
                case NO_ASYNC_TASK:
                    Bitmap bitmap = downloadBitmap(url);
                    addBitmapToCache(url, bitmap);
                    imageView.setImageBitmap(bitmap);
                    break;

                case NO_DOWNLOADED_DRAWABLE:
                    imageView.setMinimumHeight(156);
                    BitmapDownloaderTask task = new BitmapDownloaderTask(imageView);
                    task.execute(url);
                    break;

                case CORRECT:
                    task = new BitmapDownloaderTask(imageView);
                    DownloadedDrawable downloadedDrawable = new DownloadedDrawable(task);
                    imageView.setImageDrawable(downloadedDrawable);
                    imageView.setMinimumHeight(156);
                    task.execute(url);
                    break;
            }
        }
    }

    /**
     * Returns true if the current download has been canceled or if there was no download in
     * progress on this image view.
     * Returns false if the download in progress deals with the same url. The download is not
     * stopped in that case.
     */
    private static boolean cancelPotentialDownload(String url, ImageView imageView) {
        BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);

        if (bitmapDownloaderTask != null) {
            String bitmapUrl = bitmapDownloaderTask.url;
            if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
                bitmapDownloaderTask.cancel(true);
            } else {
                // The same URL is already being downloaded.
                return false;
            }
        }
        return true;
    }

    /**
     * @param imageView Any imageView
     * @return Retrieve the currently active download task (if any) associated with this imageView.
     * null if there is no such task.
     */
    private static BitmapDownloaderTask getBitmapDownloaderTask(ImageView imageView) {
        if (imageView != null) {
            Drawable drawable = imageView.getDrawable();
            if (drawable instanceof DownloadedDrawable) {
                DownloadedDrawable downloadedDrawable = (DownloadedDrawable)drawable;
                return downloadedDrawable.getBitmapDownloaderTask();
            }
        }
        return null;
    }

    Bitmap downloadBitmap(String url) {
        //final int IO_BUFFER_SIZE = 4 * 1024;

        // AndroidHttpClient is not allowed to be used from the main thread
        final HttpClient client = (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() :
            AndroidHttpClient.newInstance("Android");
        final HttpGet getRequest = new HttpGet(url);

        try {
            HttpResponse response = client.execute(getRequest);
            final int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode != HttpStatus.SC_OK) {
                Log.w("ImageDownloader", "Error " + statusCode +
                        " while retrieving bitmap from " + url);
                return null;
            }

            final HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream inputStream = null;
                try {
                    inputStream = entity.getContent();
                    // return BitmapFactory.decodeStream(inputStream);
                    // Bug on slow connections, fixed in future release.
                    return BitmapFactory.decodeStream(new FlushedInputStream(inputStream));
                } finally {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    entity.consumeContent();
                }
            }
        } catch (IOException e) {
            getRequest.abort();
            Log.w(LOG_TAG, "I/O error while retrieving bitmap from " + url, e);
        } catch (IllegalStateException e) {
            getRequest.abort();
            Log.w(LOG_TAG, "Incorrect URL: " + url);
        } catch (Exception e) {
            getRequest.abort();
            Log.w(LOG_TAG, "Error while retrieving bitmap from " + url, e);
        } finally {
            if ((client instanceof AndroidHttpClient)) {
                ((AndroidHttpClient) client).close();
            }
        }
        return null;
    }

    /*
     * An InputStream that skips the exact number of bytes provided, unless it reaches EOF.
     */
    static class FlushedInputStream extends FilterInputStream {
        public FlushedInputStream(InputStream inputStream) {
            super(inputStream);
        }

        @Override
        public long skip(long n) throws IOException {
            long totalBytesSkipped = 0L;
            while (totalBytesSkipped < n) {
                long bytesSkipped = in.skip(n - totalBytesSkipped);
                if (bytesSkipped == 0L) {
                    int b = read();
                    if (b < 0) {
                        break;  // we reached EOF
                    } else {
                        bytesSkipped = 1; // we read one byte
                    }
                }
                totalBytesSkipped += bytesSkipped;
            }
            return totalBytesSkipped;
        }
    }

    /**
     * The actual AsyncTask that will asynchronously download the image.
     */
    class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
        private String url;
        private final WeakReference<ImageView> imageViewReference;

        public BitmapDownloaderTask(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        /**
         * Actual download method.
         */
        @Override
        protected Bitmap doInBackground(String... params) {
            url = params[0];
            return downloadBitmap(url);
        }

        /**
         * Once the image is downloaded, associates it to the imageView
         */
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }

            addBitmapToCache(url, bitmap);

            if (imageViewReference != null) {
                ImageView imageView = imageViewReference.get();
                BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
                // Change bitmap only if this process is still associated with it
                // Or if we don't use any bitmap to task association (NO_DOWNLOADED_DRAWABLE mode)
                if ((this == bitmapDownloaderTask) || (mode != Mode.CORRECT)) {
                    imageView.setImageBitmap(bitmap);
                }
            }
        }
    }

    /**
     * A fake Drawable that will be attached to the imageView while the download is in progress.
     *
     *
Contains a reference to the actual download task, so that a download task can be stopped
     * if a new binding is required, and makes sure that only the last started download process can
     * bind its result, independently of the download finish order.

     */
    static class DownloadedDrawable extends ColorDrawable {
        private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

        public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
            super(Color.BLACK);
            bitmapDownloaderTaskReference =
                new WeakReference<BitmapDownloaderTask>(bitmapDownloaderTask);
        }

        public BitmapDownloaderTask getBitmapDownloaderTask() {
            return bitmapDownloaderTaskReference.get();
        }
    }

    public void setMode(Mode mode) {
        this.mode = mode;
        clearCache();
    }

    /*
     * Cache-related fields and methods.
     *
     * We use a hard and a soft cache. A soft reference cache is too aggressively cleared by the
     * Garbage Collector.
     */

    private static final int HARD_CACHE_CAPACITY = 10;
    private static final int DELAY_BEFORE_PURGE = 10 * 1000; // in milliseconds

    // Hard cache, with a fixed maximum capacity and a life duration
    private final HashMap<String, Bitmap> sHardBitmapCache =
        new LinkedHashMap<String, Bitmap>(HARD_CACHE_CAPACITY / 2, 0.75f, true) {
        /**
             *
             */
            private static final long serialVersionUID = 1L;

        @Override
        protected boolean removeEldestEntry(LinkedHashMap.Entry<String, Bitmap> eldest) {
            if (size() > HARD_CACHE_CAPACITY) {
                // Entries push-out of hard reference cache are transferred to soft reference cache
                sSoftBitmapCache.put(eldest.getKey(), new SoftReference<Bitmap>(eldest.getValue()));
                return true;
            } else
                return false;
        }
    };

    // Soft cache for bitmaps kicked out of hard cache
    private final static ConcurrentHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache =
        new ConcurrentHashMap<String, SoftReference<Bitmap>>(HARD_CACHE_CAPACITY / 2);

    private final Handler purgeHandler = new Handler();

    private final Runnable purger = new Runnable() {
        public void run() {
            clearCache();
        }
    };

    /**
     * Adds this bitmap to the cache.
     * @param bitmap The newly downloaded bitmap.
     */
    private void addBitmapToCache(String url, Bitmap bitmap) {
        if (bitmap != null) {
            synchronized (sHardBitmapCache) {
                sHardBitmapCache.put(url, bitmap);
            }
        }
    }

    /**
     * @param url The URL of the image that will be retrieved from the cache.
     * @return The cached bitmap or null if it was not found.
     */
    public Bitmap getBitmapFromCache(String url) {
        // First try the hard reference cache
        synchronized (sHardBitmapCache) {
            final Bitmap bitmap = sHardBitmapCache.get(url);
            if (bitmap != null) {
                // Bitmap found in hard cache
                // Move element to first position, so that it is removed last
                sHardBitmapCache.remove(url);
                sHardBitmapCache.put(url, bitmap);
                return bitmap;
            }
        }

        // Then try the soft reference cache
        SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(url);
        if (bitmapReference != null) {
            final Bitmap bitmap = bitmapReference.get();
            if (bitmap != null) {
                // Bitmap found in soft cache
                return bitmap;
            } else {
                // Soft reference has been Garbage Collected
                sSoftBitmapCache.remove(url);
            }
        }

        return null;
    }

    /**
     * Clears the image cache used internally to improve performance. Note that for memory
     * efficiency reasons, the cache will automatically be cleared after a certain inactivity delay.
     */
    public void clearCache() {
        sHardBitmapCache.clear();
        sSoftBitmapCache.clear();
    }

    /**
     * Allow a new delay before the automatic cache clear is done.
     */
    private void resetPurgeTimer() {
        purgeHandler.removeCallbacks(purger);
        purgeHandler.postDelayed(purger, DELAY_BEFORE_PURGE);
    }
}