WPF. MVVM. Как сохранить состояние Checked массива toggleButton

145
30 июня 2019, 16:30

Есть коллекция radiobutton, по нажатии на каждую такую кнопку формируется коллекция togglebutton. Данные для формирования и того и другого списка берутся из viewModel с помощью binding.

Есть ли способ сохранять состояния нажатых кнопок для каждой togglebutton. В идеале хотелось бы подсвечивать те radiobutton, для которых выбрана хоть одна toggle.

<!--Список радиокнопок-->
<ItemsControl Grid.Column="2"
              Grid.Row="2"
              Name="InDiamVM"
              Margin="2"
              ItemsSource="{Binding RebarsView}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <RadioButton GroupName="InDiam"
                                     Content="{Binding}"
                                     Command="{Binding Path=DataContext.ManageCurrntInDiamCommand, ElementName=InDiamVM}"
                                     Name="InDiamButtonVM"
                                     Style="{StaticResource StyleToggle}"
                                     Margin="1"
                                     Padding="2">
                <RadioButton.CommandParameter>
                    <MultiBinding Converter="{StaticResource CommandParameterConverter}">
                        <Binding ElementName="InDiamButtonVM"
                                         Path="Content" />
                        <Binding ElementName="InDiamButtonVM"
                                         Path="Name" />
                    </MultiBinding>
                </RadioButton.CommandParameter>
            </RadioButton>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
<!--Список togglebutton-->
<ItemsControl Grid.Column="3"
                            Grid.Row="2"
                            Name="OutDiamVM"
                            Margin="2"
                            ItemsSource="{Binding OutDiameters}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ToggleButton Content="{Binding }"
                                        Command="{Binding Path=DataContext.ManageCurrntOutDiamCommand, ElementName=OutDiamVM}"
                                        Name="OutDiamButtonVM"
                                        Margin="1"
                                        Padding="2">
                <ToggleButton.CommandParameter>
                    <MultiBinding Converter="{StaticResource CommandParameterConverter}">
                        <Binding ElementName="OutDiamButtonVM"
                                         Path="IsChecked" />
                        <Binding ElementName="OutDiamButtonVM"
                                         Path="Content" />
                    </MultiBinding>
                </ToggleButton.CommandParameter>
            </ToggleButton>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Часть viewModel, что отвечает за представление

// DependencyProperty для коллекции radiobutton
public ICollectionView RebarsView
{
    get { return (ICollectionView)GetValue(RebarsViewProperty); }
    set { SetValue(RebarsViewProperty, value); }
}
// Using a DependencyProperty as the backing store for RebarsView.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty RebarsViewProperty =
    DependencyProperty.Register("RebarsView", typeof(ICollectionView), typeof(AnchorageViewModel), new PropertyMetadata(null));

// DependencyProperty для выбранной кнопки radiobutton  
public RebarProperties FocusedRebar
{
    get { return (RebarProperties)GetValue(FocusedRebarProperty); }
    set { SetValue(FocusedRebarProperty, value); }
}
// Using a DependencyProperty as the backing store for FocusedRebar.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty FocusedRebarProperty =
    DependencyProperty.Register("FocusedRebar", typeof(RebarProperties), typeof(AnchorageViewModel), new PropertyMetadata(null));

// Команда для получения нужной коллекции в зависимости от положения radiobutton
public RelayCommand ManageCurrntInDiamCommand { get; private set; }
public void ManageCurrntInDiam(object o)
{
    var parameters = o as object[];
    FocusedRebar = parameters[0] as RebarProperties;
    if (FocusedSteel == null)
    {
        return;
    }
    //Выборка нужного массива для формирования коллекции togglebutton
    OutDiameters = CollectionViewSource.GetDefaultView(FocusedSteel.DiametersPermitted.Where(s => s.Diameter <= FocusedRebar.Diameter));
}

// DependencyProperty для коллекции togglebutton
public ICollectionView OutDiameters
{
    get { return (ICollectionView)GetValue(OutDiametersProperty); }
    set { SetValue(OutDiametersProperty, value); }
}
// Using a DependencyProperty as the backing store for OutDiameters.  This enables animation, styling, binding, etc...
public static readonly DependencyProperty OutDiametersProperty =
    DependencyProperty.Register("OutDiameters", typeof(ICollectionView), typeof(AnchorageViewModel), new PropertyMetadata(null));
// DependencyProperty для коллекции выбранных toggle button
public ObservableCollection<RebarProperties> currentOutDiams = new ObservableCollection<RebarProperties>();
public RelayCommand ManageCurrntOutDiamCommand { get; private set; }
public void ManageCurrntOutDiam(object o)
{
    var parameters = o as object[];
    if ((bool)parameters[0] == true)
    {
        if (SteelToDiam.ContainsKey(FocusedSteel))
        {
            if (SteelToDiam[FocusedSteel].ContainsKey(FocusedRebar))
            {
                SteelToDiam[FocusedSteel][FocusedRebar].Add(parameters[1] as RebarProperties);
            }
            else
            {
                SteelToDiam[FocusedSteel].Add(FocusedRebar, new HashSet<RebarProperties>() { parameters[1] as RebarProperties });
            }
        }
        else
        {
            SteelToDiam.Add(FocusedSteel, new Dictionary<RebarProperties, HashSet<RebarProperties>>()
                {
                    {FocusedRebar,  new HashSet<RebarProperties>() { parameters[1] as RebarProperties }}
                });
        }
    }
    else
    {
        SteelToDiam[FocusedSteel][FocusedRebar].Remove(parameters[1] as RebarProperties);
    }
    // метод, который реализует обновление информации (в data grid, где она отображается)
    UpdateInfo();
}
READ ALSO
Screenshot в консольном приложении

Screenshot в консольном приложении

Нашёл только ответ, как сделать в приложении с Windows Forms, вот этот код:

126
Не работает концентратор SignaR

Не работает концентратор SignaR

Концентратор передается в IhostedService сервис через servicesAddSingleton:

96
Передача массива по AJAX на PHP backend

Передача массива по AJAX на PHP backend

Использую AJAX и передаю массив с даннымиСам массив полностью рабочий (в плане, через js выводится, всё ок, но по ajax в php не передается, точнее...

146