A propósito de las DataGrids

Situación: tienes una DataGrid y una de las columnas es una DataGridCheckBoxColumn.

Ahora pretendes que el IsEnabled de cada CheckBox tenga un valor en base a un binding, o no.

Atiende, que viene código finicky!

<my:DataGridCheckBoxColumn.CellStyle>

    <Style>

        <Setter Property="CheckBox.IsEnabled" Value="{Binding c1, Converter={StaticResource cvt}}"/>

   </Style>

</my:DataGridCheckBoxColumn.CellStyle> 

OPPA CELLSTYLE! Gracias, Sergio por tu aporte Smile

Patrón Messenger para hacer golferías

¡Esto es casi un hack, casi una trampa!

Observa y caga blandito con este ejemplo de un árbol generado en el ViewModel y representado en la vista. Al pulsar sobre un nodo ¡el ViewModel se entera de todo! ¡Es un topo! Te empaqueto el ejemplo porque sé que un día de estos se te va a olvidar y lo querrás todo mascadito. Golfo, que eres un golfo.

image

Así queda el temario, para que identifiques claramente qué cojones vamos a hacer.

https://skydrive.live.com/redir?resid=C8B0DBB75540E8D5!25872&authkey=!AAmYXeD4O0cUpyA

Y sobre todo, atento a esta parte:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using GalaSoft.MvvmLight;
using System.Linq;
using GalaSoft.MvvmLight.Messaging;

namespace Tree.ViewModel
{
    /// &lt;summary&gt;
    /// This class contains properties that the main View can data bind to.
    /// 
    /// Use the &lt;strong&gt;mvvminpc&lt;/strong&gt; snippet to add bindable properties to this ViewModel.
    /// 
    /// 
    /// You can also use Blend to data bind with the tool's support.
    /// 
    /// 
    /// See http://www.galasoft.ch/mvvm
    /// 
    /// &lt;/summary&gt;
    public class MainViewModel : ViewModelBase
    {
        private ObservableCollection _form;
        private Form _selectedForm;


        /// &lt;summary&gt;
        /// Initializes a new instance of the MainViewModel class.
        /// &lt;/summary&gt;
        public MainViewModel()
        {
            ////if (IsInDesignMode)
            ////{
            ////    // Code runs in Blend --&amp;gt; create design time data.
            ////}
            ////else
            ////{
            ////    // Code runs &quot;for real&quot;
            ////}

            var modeloForms = new ObservableCollection
                        {
                            new Form{ 
                                Name = &quot;Form1&quot;,
                                Children = new Collection
                                               {
                                                   new Form{ 
                                                       Name = &quot;Hijo 1&quot;,
                                                       Children = new Collection
                                                                      {
                                                                          
                                                                          new Form {Name = &quot;Hijillo pequeño 1&quot;},
                                                                      }
                                                   },
                                                   new Form{ Name = &quot;Hijo 2&quot;},
                                               },


                            }
                        };
          
            Forms = new ObservableCollection(modeloForms.Select(form =&amp;gt; new FormViewModel(form)));

            Messenger.Default.Register&amp;lt;PropertyChangedMessage&amp;gt;(
              this,
              OnIsSelectedChanged);
        }

        private void OnIsSelectedChanged(PropertyChangedMessage obj)
        {
            var viewModel = obj.Sender as FormViewModel;
            if (viewModel != null &amp;amp;&amp;amp; viewModel.Children == null)
            {
                SelectedForm = viewModel.Form;
            }
        }

        public ObservableCollection Forms
        {
            get { return _form; }
            set
            {
                _form = value;
                RaisePropertyChanged(() =&amp;gt; Forms);
            }
        }

        public Form SelectedForm
        {
            get { return _selectedForm; }
            set
            {
                _selectedForm = value;
                RaisePropertyChanged(() =&amp;gt; SelectedForm);
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;

namespace Tree
{
    public class FormViewModel : ViewModelBase
    {
        private Form _form;
        private bool _isSelected;
        private IList _children;

        public FormViewModel(Form form)
        {
            _form = form;

            if (form.Children != null)
            {
                Children = form.Children.Select(form1 =&gt; new FormViewModel(form1)).ToList();
            }
        }


        public Form Form
        {
            get { return _form; }
            set
            {
                _form = value;
                RaisePropertyChanged(() =&gt; Form);
            }
        }

        public IList Children
        {
            get { return _children; }
            set
            {
                _children = value;
                RaisePropertyChanged(() =&gt; Children);
            }
        }

        public bool IsSelected
        {
            get
            {
                return _isSelected;
            }
            set
            {
                var old = _isSelected;
                _isSelected = value;
                RaisePropertyChanged(() =&gt; IsSelected, old, value, true);
            }
        }



    }
}

Pego el codiguejo para que además tengas ese apoyo visual que tanto nos gusta. Y qué pongo aquí? Pues el RaisePropertyChanged con 4 parámetros. Surprising! Bueno, ¡pruébalo y saborea su miel YA!

Google es un monstruo

Hay gente que odia a Microsoft.

Siempre ha habido y habrá “haters” o lo que es lo mismo, el opuesto de “fanboy”. De Microsoft los hay a puñados porque existe el tópico de que todo lo que huele a Microsoft significa borreguismo, mediocridad y malas artes, cosa que fue cierto hace años. Ahora la cosa ha cambiado bastante.

Google está siguiendo los pasos del otrora gigante M$. Compra empresas, calla a la competencia, fuerza incompatilidades, margina tecnologías porque “no le interesan”, compra patentes y las utiliza en juicios millonarios, ofrece servicios premium, recaba información de todo lo que hacemos, recoge datos públicos, los cataloga y los convierte en servicios de pago (Google Maps)…

¿En qué se diferencia del más pésimo Microsoft de hace años o de cualquier otra empresa? Os diré en qué: en que Google es aún más fuerte. Lo único que mantiene a esta empresa (de momento) sin dar un puñetazo en la mesa y mostrarse como el monstruo que es, es que sabe que su popularidad depende de esa cretina idea de candidez y gratuidad que rodea a todo lo que lleva la marca Google.

image

¡Descubre el maravillo mundo del SelectedValuePath!

Si tu vida no tiene sentido y de repente ves todo oscuro, sientes ganas de llorar y tan solo recuerdas tu niñez comiendo bocatas de jamón y queso, es hora de descubrir una nueva razón de tu vivir. Tu existencia cobrará sentido automáticamente.

Ya fuera de cachondeo. Si tienes un jodido Binding entre datos curiosos, tales como un tupla clave / valor, y en un ComboBox representas el valor, pero te basas en la clave para que se sincronicen varios elementos enlazados por Binding, prueba a usar SelectedValue en el Binding y NO TE OLVIDES: estamos aquí por él, ¡el famoso SelectedValuePath!

Ejemplo:

&lt;ComboBox 
    DisplayMemberPath=&quot;Value&quot; 
    SelectedValuePath=&quot;Key&quot; 
    ItemsSource=&quot;{Binding Source={res:LocalEnumExtension {x:Type local:OperationType}}}&quot;
    SelectedValue=&quot;{Binding SelectedVariable.Operation.Type}&quot; 
    IsEnabled=&quot;{Binding SelectedVariable, Converter={StaticResource IsNotNullConverter}}&quot; 
    HorizontalContentAlignment=&quot;Stretch&quot; HorizontalAlignment=&quot;Left&quot; Margin=&quot;383,100,0,205&quot; 
    VerticalAlignment=&quot;Center&quot; Height=&quot;30&quot; Width=&quot;203&quot; /&gt;

El ItemSource nos devuelve tuplas de diccionario tal que así KeyValuePair<Enum, string>, que por cierto, también es un tema que trataré mañana.

De esta manera, asociamos la Key con el con el enumerado que sea seleccionado en cada Operation.Type.

Espero que lo hayas disfrutado. Eso sí, no tenía ni puta idea de cómo se hacía hasta hoy. ¡YIEEEEEHAA!