Bindowanie do kontrolki ComboBox

0

Cześć, może ktoś będzie w stanie pomóc mi rozwiązać problem z którym już od jakiegoś czasu się męczę
Mianowicie chce po prostu do ComboBox wstawić listę elementów z kodu źródłowego. Robię to w taki sposób:

Okno WPF

<mah:MetroWindow x:Class="AlarmConfiguration.Lines.LineSettingsRadio"
        xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AlarmConfiguration.Lines"
        xmlns:resx="clr-namespace:AlarmConfiguration.Resources" d:DataContext="{d:DesignInstance Type=local:Line}"
        mc:Ignorable="d"
        Title="{x:Static resx:Translations.RemoteConfig}" Height="220" Width="320" Closed="MetroWindow_Closed">
    
    <StackPanel Orientation="Vertical">
        <CheckBox Content="Linia 24h"/>
        <ComboBox SelectedItem="{Binding Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}">
            <Style TargetType="{x:Type ComboBox}">
                <Setter Property="ItemsSource" Value="{Binding LineTypes}" />
                <Setter Property="VerticalAlignment" Value="Center" />
            </Style>
        </ComboBox>
    </StackPanel>   
</mah:MetroWindow>

Dane w pliku Lines i znajdujące się w takiej przestrzeni


        [MarshalAs(UnmanagedType.I1)] public LineType lineType = LineType.NotUsed;


        public string Type
        {
            get => Converter.EnumDescription.GetDescription(thisLine.lineType);
            set
            {
                foreach (var lineType in Enum.GetValues(typeof(LineType)).Cast<LineType>())
                {
                    if (Converter.EnumDescription.GetDescription(lineType) == value)
                    {
                        thisLine.lineType = lineType;
                        break;
                    }
                }
                OnPropertyChanged();
            }
        }


        public static IEnumerable<string> LineTypes
        {
            get
            {
                yield return Converter.EnumDescription.GetDescription(LineType.NotUsed);
                foreach (var lineType in Enum.GetValues(typeof(LineType)).Cast<LineType>())
                {
                    if(lineType != LineType.NotUsed)
                        yield return Converter.EnumDescription.GetDescription(lineType);
                }
            }
        }

        public enum LineType : byte
        {
            [LocalizedDescription("LineTypeEntryExit1", typeof(Translations))] Enter_Exit_1 = 0,
            [LocalizedDescription("LineTypeEntryExit2", typeof(Translations))] Enter_Exit_2 = 1,
            [LocalizedDescription("LineTypeInternal", typeof(Translations))] Internal = 2,
            [LocalizedDescription("LineTypeInstant", typeof(Translations))] Instant = 3,
            //[LocalizedDescription("LineTypeJointly", typeof(Translations))] Jointly = 4,
            [LocalizedDescription("LineTypeNotUsed", typeof(Translations))] NotUsed = 5,
            [LocalizedDescription("LineTypeFire24", typeof(Translations))] Fire24 = 6,
            [LocalizedDescription("LineTypeBreakingIn24", typeof(Translations))] BreakingIn24 = 7,
        }

W efekcie obecnie mam w ComboBoxie tekst: System.Windows.Style

0

U ciebie pojawia się <ComboBox SelectedItem="{Binding Type (...). Nie wiemy czym jest Type, mimo wszystko wydaje mi się że powinieneś bindować do LineTypes. https://stackoverflow.com/a/21898127

Poza tym sugeruję się upewnić że getter dla LineTypes zwraca poprawne wartości.

0

Wydaję mi się, że to kwestia braku ItemTemplate w Twoim kodzie.

<ComboBox ItemsSource="{Binding LineTypes}" SelectedItem="{Binding Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}">
<ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="{Binding}"/>
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>
0
        <ComboBox SelectedItem="{Binding Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}">
            <ComboBox.Style>
                <Style TargetType="{x:Type ComboBox}">
                    <Setter Property="ItemsSource" Value="{Binding LineTypes}" />
                    <Setter Property="SelectedIndex" Value="0" />
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
            </ComboBox.Style>
        </ComboBox>

Dodałem jeszcze <ComboBox.Style> i teraz przynajmniej pole na listę jest właściwej wielkości. Nadal jest jednak pusta i obsługa nie wchodzi do settera LineTypes, ale przynajmniej wygląda jakby była widoczna wielkość listy

0

@danielbr3: Gdzie masz ItemsSource w swoim przykadzie?

0
danielbr3 napisał(a):
        <ComboBox SelectedItem="{Binding Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}">
            <ComboBox.Style>
                <Style TargetType="{x:Type ComboBox}">
                    <Setter Property="ItemsSource" Value="{Binding LineTypes}" />
                    <Setter Property="SelectedIndex" Value="0" />
                    <Setter Property="VerticalAlignment" Value="Center" />
                </Style>
            </ComboBox.Style>
        </ComboBox>

Dodałem jeszcze <ComboBox.Style> i teraz przynajmniej pole na listę jest właściwej wielkości. Nadal jest jednak pusta i obsługa nie wchodzi do settera LineTypes, ale przynajmniej wygląda jakby była widoczna wielkość listy

Może ktoś bardziej obeznany w WPF napisze Ci jak powinno się mapować statycznego propa.
Takie coś u mnie działa dla Twojego kodu z zacytowanego posta.

W przykładzie używam SetProperty i ObservableObject z Mvvm toolkit - https://learn.microsoft.com/en-us/dotnet/api/microsoft.toolkit.mvvm.componentmodel.observableobject.setproperty?view=win-comm-toolkit-dotnet-7.1

public TestViewModel : ObservableObject
{
  public TestViewModel(ISettingsProvider settingsProvider)
  {
      LineTypes = GetLineTypes();
  }
  
  private IEnumerable<string> GetLineTypes()
  {
      yield return Converter.EnumDescription.GetDescription(LineType.NotUsed);
      foreach (var lineType in Enum.GetValues(typeof(LineType)).Cast<LineType>())
      {
          if (lineType != LineType.NotUsed)
              yield return Converter.EnumDescription.GetDescription(lineType);
      }
  }
  private IEnumerable<string> lineType;
  public IEnumerable<string> LineTypes
  {
      get { return lineType; }
      set { SetProperty(ref lineType, value); }
  }
//...
}

Edit: Nie zauważyłem, że usunąłeś DataTemplate. Poniżej kod z Setterem w xaml:

<ComboBox SelectedItem="{Binding Type, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged, NotifyOnValidationError=True}">
    <ComboBox.Style>
        <Style TargetType="{x:Type ComboBox}">
            <Setter Property="ItemsSource" Value="{Binding LineTypes}" />
            <Setter Property="SelectedIndex" Value="0" />
            <Setter Property="VerticalAlignment" Value="Center" />
        </Style>
    </ComboBox.Style>
    <ComboBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Horizontal" >
            <TextBlock Text="{Binding}"/>
        </StackPanel>
    </DataTemplate>
</ComboBox.ItemTemplate>

1 użytkowników online, w tym zalogowanych: 0, gości: 1