Как динамически c включать / отключать ComboBox из ViewModel с помощью bool - PullRequest
0 голосов
/ 05 августа 2020

Я хочу, чтобы моя ComboBox была отключена, когда моя коллекция null или пуста, и была включена, когда я обновляю коллекцию и заполняю ее, так же, как моя кнопка «Подключить».

Я пробовал IsEnabled="{Binding CanConnect }", но он начинает отключаться и не включается, когда я заполняю коллекцию кнопкой uppdate.

Я набрал это с помощью MVVM:

Model.cs

internal class PuertosCollection : ObservableCollection<Puerto>
{

}
internal class Puerto
{
    public string Nombre { get; set; }
    public SerialPort Valor { get; set; }

    public override string ToString()
    {
        return Nombre;
    }
}

ViewModel.cs

public bool CanConnect
{
   get
   {
      return CurrentPuerto?.Valor.IsOpen != null;
   }
}

private ICommand conectarCommand;
public ICommand ConectarCommand
{
   get
   {
      if (conectarCommand == null)
         conectarCommand = new RelayCommand(new Action(Conectar), () => CanConnect);
      return conectarCommand;
   }
}
private void Conectar()
{
   currentPuerto.Valor.Open();
}

private Puerto currentPuerto;

public Puerto CurrentPuerto
{
   get { return currentPuerto; }
   set
   {
      currentPuerto = value;
      RaisePropertyChanged("CurrentPuerto");
   }
}

private PuertosCollection listaPuertos;
public PuertosCollection ListaPuertos
{
   get { return listaPuertos; }
   set
   {
      listaPuertos = value;
      if (value != null && value.Count > 0)
      {
         CurrentPuerto = value[0];
      }
      RaisePropertyChanged("ListaPuertos");
   }
}

private ICommand listarPuertosCommand;
public ICommand ListarPuertosCommand
{
   get
   {
      if (listarPuertosCommand == null)
         listarPuertosCommand = new RelayCommand(new Action(ListarPuertos));
      return listarPuertosCommand;
   }
}

private void ListarPuertos()
{
   ListaPuertos = Generator.Puertos();
}

View.xaml

<Window.Resources>
    <vm:ConfiguracionViewModel x:Key="ConfiguracionVM"/>
    <vm:DatoViewModel x:Key="DatoVM"/>
</Window.Resources>

<DockPanel>
    <StackPanel DataContext="{StaticResource ConfiguracionVM}" DockPanel.Dock="Top" Orientation="Horizontal" HorizontalAlignment="Left" Margin="8">
        <Button Content="Conectar" Command="{Binding ConectarCommand}" Margin="0,0,8,0"/>
        <Label Content="Puerto:" VerticalAlignment="Center"/>
        <ComboBox ItemsSource="{Binding ListaPuertos}" SelectedItem="{Binding CurrentPuerto}" IsEnabled="{Binding CanConnect }" Width="Auto" VerticalContentAlignment="Center" Margin="0,0,8,0">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Loaded">
                    <i:InvokeCommandAction Command="{Binding ListarPuertosCommand}"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </ComboBox>
        <Button Command="{Binding ListarPuertosCommand}" VerticalAlignment="Center" Margin="0,0,8,0">
            <StackPanel>
                <Image Source="/Recursos/Imagenes/actualizar_96px.png" Width="32" Height="32" />
            </StackPanel>
        </Button>
        <Button VerticalAlignment="Center">
            <StackPanel>
                <Image Source="/Recursos/Imagenes/ajustes_48px.png" Width="32" Height="32"/>
            </StackPanel>
        </Button>
    </StackPanel>
    <StatusBar DockPanel.Dock="Bottom">
        <Label Content="Statusbar"/>
    </StatusBar>
    <DataGrid DataContext="{StaticResource DatoVM}">
        
    </DataGrid>
</DockPanel>

Я учусь MVVM с в этом руководстве

Ответы [ 2 ]

0 голосов
/ 05 августа 2020

Я пробовал IsEnabled="{Binding CanConnect}", но он начинает отключаться и не включается, когда я заполняю коллекцию кнопкой uppdate.

По крайней мере, из предоставленного вами кода вы не запускаете событие изменения свойства для свойства CanConnect при его изменении.

Отключение поля со списком

Вы можете добавить стиль к ComboBox, который отключает его, если коллекция ListaPuertos null или пусто.

<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
   <Setter Property="IsEnabled" Value="True"/>
   <Style.Triggers>
      <DataTrigger Binding="{Binding ListaPuertos}" Value="{x:Null}">
         <Setter Property="IsEnabled" Value="False"/>
      </DataTrigger>
      <DataTrigger Binding="{Binding ListaPuertos.Count}" Value="0">
         <Setter Property="IsEnabled" Value="False"/>
      </DataTrigger>
   </Style.Triggers>
</Style>
0 голосов
/ 05 августа 2020

Это очень просто.

Сначала создайте преобразователь, который получает целое число, которое соответствует количеству элементов, которые у вас есть в коллекции, если количество больше нуля, он вернет True, если нет он вернет False.

using System;
using System.Windows.Data;

namespace MyProject
{
    public class CountToBoolean : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return (value is int) ? ((int)value) > 0 : false;
        }

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

Затем вы создаете экземпляр Converter в App.xaml или в окне, которое хотите его использовать.

<cv:CountToBoolean                      x:Key="CountToBoolean"/>

И, наконец, вы примените его к ComboBox:

<ComboBox ItemsSource="{Binding ListaPuertos}" SelectedItem="{Binding CurrentPuerto}" IsEnabled="{Binding ListaPuertos.Count, Converter={StaticResource CountToBoolean}}" Width="Auto" VerticalContentAlignment="Center" Margin="0,0,8,0">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding ListarPuertosCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ComboBox>

Это должно сработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...