简体   繁体   中英

Move checkbox and text to left or right on click of a button

I am pretty new to wpf. I have 5 checkboxes each with its color picker and text. I want to select a checkbox and then click < or > button to move the checkboxes left or right along with text and its color picker.

<CheckBox Content="Channel 1" HorizontalAlignment="Left" Margin="42,50,0,33" Checked="CheckBox_Checked"/>
    <CheckBox Content="Channel 2" HorizontalAlignment="Left" Margin="170,50,0,0" VerticalAlignment="Top" Checked="CheckBox_Checked"/>
    <CheckBox Content="Channel 3" HorizontalAlignment="Left" Margin="292,50,0,35" Checked="CheckBox_Checked"/>
    <CheckBox Content="Channel 6" HorizontalAlignment="Left" Margin="668,49,0,0" VerticalAlignment="Top" Checked="CheckBox_Checked"/>
    <CheckBox Content="Channel 5" HorizontalAlignment="Left" Margin="541,50,0,0" VerticalAlignment="Top" Checked="CheckBox_Checked"/>
    <CheckBox Content="Channel 4" HorizontalAlignment="Left" Margin="422,51,0,33" Checked="CheckBox_Checked"/>
    <Button Content="&lt;" HorizontalAlignment="Left" Margin="10,44,0,31" Width="27" FontSize="14" FontWeight="Bold" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
    <Button Content="&gt;" HorizontalAlignment="Left" Margin="795,44,0,31" Width="27" FontSize="14" FontWeight="Bold" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>

    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="245,46,0,0" VerticalAlignment="Top" Width="39" Height="19"/>
    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="117,46,0,0" VerticalAlignment="Top" Width="39" Height="19"/>
    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="369,46,0,0" VerticalAlignment="Top" Width="39" Height="19"/>
    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="497,47,0,0" VerticalAlignment="Top" Width="39" Height="19"/>
    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="616,47,0,0" VerticalAlignment="Top" Width="39" Height="19"/>
    <c1:C1ColorPicker HorizontalAlignment="Left" Margin="743,46,0,0" VerticalAlignment="Top" Width="39" Height="19"/>

for example if the checkboxes are aligned as

Channel 1 Channel 2 Channel 3 Channel 4 Channel 5 and i checked channel 3 and clicked < button then the new order will be Channel 1 Channel 3 Channel 2 Channel 4 Channel 5

edited:

local namespace added as : xmlns:local ="clr-namespace:WpfApplication3"

custom control EnhancedCheckBoxControl:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WpfApplication3
{
    public partial class EnhancedCheckBoxControl : CheckBox
    {

    }
}

I have implemented some little improvement (removed margin added custom control), there is much more which could be improved.

Your XAML file:

<Window.Resources>
    <Style TargetType="StackPanel">
        <Setter Property="Orientation" Value="Horizontal" />
    </Style>

    <Style TargetType="local:EnhancedCheckBoxControl">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:EnhancedCheckBoxControl">
                    <ContentControl>
                        <StackPanel Orientation="Horizontal">
                            <CheckBox Content="{TemplateBinding Content}" IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}}" />
                            <c1:C1ColorPicker Width="39" Height="19"/>
                        </StackPanel >
                    </ContentControl>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>

    <StackPanel x:Name="spToSort" Grid.Column="1">
        <local:EnhancedCheckBoxControl Content="Channel 1" />
        <local:EnhancedCheckBoxControl Content="Channel 2" />
        <local:EnhancedCheckBoxControl Content="Channel 3" />
        <local:EnhancedCheckBoxControl Content="Channel 4" />
        <local:EnhancedCheckBoxControl Content="Channel 5" />
        <local:EnhancedCheckBoxControl Content="Channel 6" />
    </StackPanel>

    <Button Content="&lt;" Grid.Column="0" Width="27" FontSize="14" FontWeight="Bold" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" Click="Button_Left"/>
    <Button Content="&gt;" Grid.Column="2" Width="27" FontSize="14" FontWeight="Bold" Background="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" BorderBrush="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}" Click="Button_Right"/>
</Grid>

The code behind for moving:

private IEnumerable<EnhancedCheckBoxControl> GetStackPanelsToMove()
{
    return spToSort.Children.OfType<EnhancedCheckBoxControl>()
        .Where(cb => cb.IsChecked.HasValue && cb.IsChecked.Value);
}

private void Button_Left(object sender, RoutedEventArgs e)
{
    IEnumerable<EnhancedCheckBoxControl> stackPanelsToMove = GetStackPanelsToMove()
        .OrderBy(sp => spToSort.Children.IndexOf(sp));

    foreach (var spToMove in stackPanelsToMove) {
        int position = spToSort.Children.IndexOf(spToMove);
        if (position <= 0) { continue; }

        spToSort.Children.Remove(spToMove);
        spToSort.Children.Insert(position - 1, spToMove);
    }
}

private void Button_Right(object sender, RoutedEventArgs e)
{
    IEnumerable<EnhancedCheckBoxControl> stackPanelsToMove = GetStackPanelsToMove()
        .OrderByDescending(sp => spToSort.Children.IndexOf(sp));

    foreach (var spToMove in stackPanelsToMove)
    {
        int position = spToSort.Children.IndexOf(spToMove);
        if (position >= spToSort.Children.Count - 1) { continue; }

        spToSort.Children.Remove(spToMove);
        spToSort.Children.Insert(position + 1, spToMove);
    }
}

The custom control is a empty class which inherits from CheckBox :

public class EnhancedCheckBoxControl : CheckBox
{
}

Your requirement is achievable very easily by placing the controls in a grid and moving them dynamically. Divide your main grid into 5 columns first. Each column consisting of a CheckBox. Now when each checkbox is checked or unchecked, you could catch the event and identify the selected checkbox. When user clicks on < button, change the column of the checkbox and its alternate checkbox using below code :

You can call SetValue on the object for which you want change the grid column value:

Checkbox3.SetValue(Grid.ColumnProperty, 2);
mainGrid.Children.Add(Checkbox3);
Checkbox2.SetValue(Grid.ColumnProperty, 3);
mainGrid.Children.Add(Checkbox2);

Assuming that you're trying to move the 3rd checkbox to the left.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM