giovedì 28 novembre 2013

WPF (MVVM) - Retrieve the Listbox SelectedItems property

C# .NET Framework 4.0 MVVM Light Toolkit

In my WPF (MVVM) application, I want to use the Listbox SelectedItems property but this property has no setter and for this reason it’s not “bindable“ to my view model.
I have tried to use the property (IsSelected) in my object and in the XAML this item container style.

<ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </Style>
</ListBox.ItemContainerStyle>

This solution works fine if the Listbox SelectionMode property is set to Single but if the selection mode is “Extended” (SelectionMode="Extended") it doesn’t work correctly, sometimes a few items remain selected.
Finally, I found a solution that works for me. I use the MenuItem’s CommandParameter for accessing to the Listbox SelectedItems property.

Like this.

<ListBox.ContextMenu>
<ContextMenu>
                    <MenuItem Command="{Binding AddImagesSelectedCommand}" CommandParameter="{Binding PlacementTarget.SelectedItems, RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}" Header="{Binding Source={StaticResource CustomResources}, Path=LocalizedStrings.mnuAddImagesSelected}" />
</ContextMenu>
</ListBox.ContextMenu> 

Then in the view model:

AddImagesSelectedCommand = new RelayCommand<object>(OnAddImagesSelected, CanAddImagesSelected);

private void OnAddImagesSelected(object param)
        {
            var selectedImages = ((IEnumerable)param).Cast<CaptureImage>().ToList();

     //To do something …           
        }   

private bool CanAddImagesSelected(object param)
        {
            if (param != null)
            {
                var selectedImages = ((IEnumerable) param).Cast<CaptureImage>().ToList();

                return (selectedImages != null && selectedImages.Count > 0);
            }
            return false;
        }

We must use the PlacementTarget object because the ContextMenu is not in the same part of the Visual Tree, so that is why you cannot use ElementName etc. to reference the ListBox.


See you soon for the next trick!

lunedì 11 novembre 2013

WPF - Zoom an image with the slider control.

C# .NET Framework 4.0

In a WPF (XAML) view I want to zoom an image using a slider control and also in this occasion the binding help me to do this with a few code rows.

<Grid>
<Grid.RowDefinitions>
             <RowDefinition Height="*"></RowDefinition>
              <RowDefinition Height="30"></RowDefinition>
       </Grid.RowDefinitions>
       <Image Grid.Row="0" Name="ImgReader" Source="Images/Exit.png" Stretch="Uniform" RenderTransformOrigin="0.5, 0.5" >
             <Image.RenderTransform>
                    <ScaleTransform ScaleX="{Binding ElementName=SliderDocument, Path=Value}" ScaleY="{Binding ElementName=SliderDocument, Path=Value}"/>
              </Image.RenderTransform>
       </Image>
       <Slider Grid.Row="1" Name="SliderDocument" VerticalAlignment="Center" Minimum="0.1" Maximum="1" />
</Grid>


It’s great!

Strange error: 'DockingManager' does not exist in XML namespace ...' - Unblock DLL

C# .NET Framework 4.0

I have had a strange error in my WPF application when I referenced an external library (Xceed.Wpf.AvalonDock.dll).

This error

 Error The tag 'DockingManager' does not exist in XML namespace 'http://avalondock.codeplex.com'. Line 41 Position 10.

 appeared at design time but not at run-time, so after a few hours I’ve founded that this was a “security error”, because Windows protects you from components downloaded from the Internet.



After that I clicked on “Unblock” and the error is missed.

Thanks Microsoft … :-|