Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Listbox IsSynchronizedWithCurrentItem导致选择第一个项目,即使没有任何命令它这样做_C#_Wpf_Xaml_Combobox_Listbox - Fatal编程技术网

C# Listbox IsSynchronizedWithCurrentItem导致选择第一个项目,即使没有任何命令它这样做

C# Listbox IsSynchronizedWithCurrentItem导致选择第一个项目,即使没有任何命令它这样做,c#,wpf,xaml,combobox,listbox,C#,Wpf,Xaml,Combobox,Listbox,我在wpf列表框中发现了一些可能是bug的东西。请看代码,然后我解释发生了什么 窗口 <Window > <Grid> <local:MultiSelectionComboBox Width="200" MinHeight="25" HorizontalAlignment="Center"

我在wpf列表框中发现了一些可能是bug的东西。请看代码,然后我解释发生了什么

窗口

<Window >
<Grid>
    <local:MultiSelectionComboBox Width="200"
                                  MinHeight="25"
                                  HorizontalAlignment="Center"
                                  VerticalAlignment="Center"
                                  ASLDisplayMemberPath="FirstName"
                                  ASLSelectedItems="{Binding SelectedModels}"
                                  ItemsSource="{Binding Models}" />
    <ListBox HorizontalAlignment="Right"
             VerticalAlignment="Top"
             DisplayMemberPath="FirstName"
             ItemsSource="{Binding SelectedModels}" />
</Grid>
</Window>

用户控制

<ComboBox>
<ComboBox.Style>
    <Style TargetType="{x:Type ComboBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid x:Name="MainGrid"
                          Width="Auto"
                          Height="Auto"
                          SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="0" />
                        </Grid.ColumnDefinitions>
                        <Popup x:Name="PART_Popup"
                               Grid.ColumnSpan="2"
                               Margin="1"
                               AllowsTransparency="true"
                               IsOpen="{Binding Path=IsDropDownOpen,
                                                RelativeSource={RelativeSource TemplatedParent}}"
                               Placement="Center"
                               PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
                            <Border x:Name="DropDownBorder"
                                    MinWidth="{Binding Path=ActualWidth,
                                                       ElementName=MainGrid}"
                                    MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <ScrollViewer CanContentScroll="true">
                                    <StackPanel>
                                        <CheckBox x:Name="checkBox" 
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=CheckAllCommand}">select all</CheckBox>
                                        <ListBox x:Name="lstBox"
here lies the problem without the line below I dont get to see the result on start up,
with the it selects the first item even if nothing is triggering it
                                                 IsSynchronizedWithCurrentItem="True"
                                                 ItemsSource="{TemplateBinding ItemsSource}"
                                                 KeyboardNavigation.DirectionalNavigation="Contained"
                                                 SelectionChanged="ListBoxOnSelectionChanged"
                                                 SelectionMode="Multiple"
                                                 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                    </StackPanel>
                                </ScrollViewer>
                            </Border>
                        </Popup>
                        <ToggleButton Grid.ColumnSpan="2"
                                      MinWidth="20"
                                      HorizontalAlignment="Right"
                                      Background="{TemplateBinding Background}"
                                      BorderBrush="{TemplateBinding BorderBrush}"
                                      IsChecked="{Binding Path=IsDropDownOpen,
                                                          Mode=TwoWay,
                                                          RelativeSource={RelativeSource TemplatedParent}}"
                                      Style="{DynamicResource ToggleButtonStyle1}" />
                        <ItemsControl x:Name="itemsControl"
                                      Margin="4,2,0,2"
                                      ItemsSource="{Binding Path=SelectedItems,
                                                            ElementName=lstBox}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border Margin="1"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Background="#383838"
                                            CornerRadius="2"
                                            Padding="5,2,3,2">
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock x:Name="Test"
                                                       Foreground="White"
                                                       Loaded="Test_OnLoaded"
                                                       Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                                     AncestorType={x:Type ComboBox}},
                                                                      Path=ASLDisplayMemberPathActualValue}" />
                                            <Button Width="12"
                                                    Height="12"
                                                    Margin="5,0,0,0"
                                                    Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                                     AncestorType=ComboBox},
                                                                      Path=UnselectCommand}"
                                                    CommandParameter="{Binding}">
                                                <Button.Template>
                                                    <ControlTemplate TargetType="{x:Type Button}">
                                                        <Grid>
                                                            <Ellipse x:Name="PART_ButtonBackground"
                                                                     Fill="White"
                                                                     Opacity="0" />
                                                            <TextBlock x:Name="PART_Text"
                                                                       Margin="0,0,0,1"
                                                                       HorizontalAlignment="Center"
                                                                       VerticalAlignment="Center"
                                                                       FontSize="10"
                                                                       Foreground="White"
                                                                       Text="X" />
                                                        </Grid>
                                                        <ControlTemplate.Triggers>
                                                            <Trigger Property="IsMouseOver" Value="True">
                                                                <Setter TargetName="PART_ButtonBackground" Property="Opacity" Value="0.8" />
                                                                <Setter TargetName="PART_Text" Property="Foreground" Value="Black" />
                                                            </Trigger>
                                                        </ControlTemplate.Triggers>
                                                    </ControlTemplate>
                                                </Button.Template>
                                            </Button>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ComboBox.Style>
</ComboBox>
public partial class MultiSelectionComboBox : ComboBox
{
    #region fields, dependencies, command and constructor
    private ListBox listBox;
    private ItemsControl itemsControl;
    private CheckBox checkBox;

    public static readonly DependencyProperty ASLSelectedItemsProperty = DependencyProperty.Register("ASLSelectedItems", typeof(ObservableCollection<object>), typeof(MultiSelectionComboBox), new PropertyMetadata(null));
    public static readonly DependencyProperty ASLDisplayMemberPathProperty = DependencyProperty.Register("ASLDisplayMemberPath", typeof(string), typeof(MultiSelectionComboBox), new PropertyMetadata("Description"));

    public MultiSelectionComboBox()
    {
        InitializeComponent();
    }

    public DelegateCommand<object> UnselectCommand { get; private set; }
    public DelegateCommand CheckAllCommand { get; private set; }

    public ObservableCollection<object> ASLSelectedItems
    {
        get { return (ObservableCollection<object>)GetValue(ASLSelectedItemsProperty); }
        set { SetValue(ASLSelectedItemsProperty, value); }
    }

    public string ASLDisplayMemberPath
    {
        get { return (string)GetValue(ASLDisplayMemberPathProperty); }
        set { SetValue(ASLDisplayMemberPathProperty, value); }
    }
    #endregion

    private void CheckAll()
    {
        if (checkBox.IsChecked == true)
        {
            listBox.SelectAll();

        }
        else
        {
            listBox.UnselectAll();
        }
    }

    private void GetControls()
    {
        checkBox = Template.FindName("checkBox", this) as CheckBox;
        listBox = Template.FindName("lstBox", this) as ListBox;
        itemsControl = Template.FindName("itemsControl", this) as ItemsControl;
    }

    private bool bug = true;
    private void ListBoxOnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        e.AddedItems.Cast<object>().Where(item => !ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Add(p));
        e.RemovedItems.Cast<object>().Where(item => ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Remove(p));
        checkBox.IsChecked = (listBox.ItemsSource as IList).Count == listBox.SelectedItems.Count;
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        GetControls();
        SetControls();
        UnselectCommand = new DelegateCommand<object>(p => listBox?.SelectedItems.Remove(p));
        CheckAllCommand = new DelegateCommand(CheckAll);
    }

    private void SetControls()
    {
        listBox.DisplayMemberPath = ASLDisplayMemberPath;
        itemsControl.DisplayMemberPath = ASLDisplayMemberPath;
    }

    private void Test_OnLoaded(object sender, RoutedEventArgs e)
    {
        (sender as TextBlock)?.SetBinding(TextBlock.TextProperty, ASLDisplayMemberPath);
    }
}

全选
代码隐藏用户控件

<ComboBox>
<ComboBox.Style>
    <Style TargetType="{x:Type ComboBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ComboBox}">
                    <Grid x:Name="MainGrid"
                          Width="Auto"
                          Height="Auto"
                          SnapsToDevicePixels="true">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="0" />
                        </Grid.ColumnDefinitions>
                        <Popup x:Name="PART_Popup"
                               Grid.ColumnSpan="2"
                               Margin="1"
                               AllowsTransparency="true"
                               IsOpen="{Binding Path=IsDropDownOpen,
                                                RelativeSource={RelativeSource TemplatedParent}}"
                               Placement="Center"
                               PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}">
                            <Border x:Name="DropDownBorder"
                                    MinWidth="{Binding Path=ActualWidth,
                                                       ElementName=MainGrid}"
                                    MaxHeight="{TemplateBinding MaxDropDownHeight}">
                                <ScrollViewer CanContentScroll="true">
                                    <StackPanel>
                                        <CheckBox x:Name="checkBox" 
Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ComboBox}, Path=CheckAllCommand}">select all</CheckBox>
                                        <ListBox x:Name="lstBox"
here lies the problem without the line below I dont get to see the result on start up,
with the it selects the first item even if nothing is triggering it
                                                 IsSynchronizedWithCurrentItem="True"
                                                 ItemsSource="{TemplateBinding ItemsSource}"
                                                 KeyboardNavigation.DirectionalNavigation="Contained"
                                                 SelectionChanged="ListBoxOnSelectionChanged"
                                                 SelectionMode="Multiple"
                                                 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                    </StackPanel>
                                </ScrollViewer>
                            </Border>
                        </Popup>
                        <ToggleButton Grid.ColumnSpan="2"
                                      MinWidth="20"
                                      HorizontalAlignment="Right"
                                      Background="{TemplateBinding Background}"
                                      BorderBrush="{TemplateBinding BorderBrush}"
                                      IsChecked="{Binding Path=IsDropDownOpen,
                                                          Mode=TwoWay,
                                                          RelativeSource={RelativeSource TemplatedParent}}"
                                      Style="{DynamicResource ToggleButtonStyle1}" />
                        <ItemsControl x:Name="itemsControl"
                                      Margin="4,2,0,2"
                                      ItemsSource="{Binding Path=SelectedItems,
                                                            ElementName=lstBox}">
                            <ItemsControl.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <WrapPanel IsItemsHost="True" Orientation="Horizontal" />
                                </ItemsPanelTemplate>
                            </ItemsControl.ItemsPanel>
                            <ItemsControl.ItemTemplate>
                                <DataTemplate>
                                    <Border Margin="1"
                                            HorizontalAlignment="Left"
                                            VerticalAlignment="Top"
                                            Background="#383838"
                                            CornerRadius="2"
                                            Padding="5,2,3,2">
                                        <StackPanel Orientation="Horizontal">
                                            <TextBlock x:Name="Test"
                                                       Foreground="White"
                                                       Loaded="Test_OnLoaded"
                                                       Text="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                                     AncestorType={x:Type ComboBox}},
                                                                      Path=ASLDisplayMemberPathActualValue}" />
                                            <Button Width="12"
                                                    Height="12"
                                                    Margin="5,0,0,0"
                                                    Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor,
                                                                                                     AncestorType=ComboBox},
                                                                      Path=UnselectCommand}"
                                                    CommandParameter="{Binding}">
                                                <Button.Template>
                                                    <ControlTemplate TargetType="{x:Type Button}">
                                                        <Grid>
                                                            <Ellipse x:Name="PART_ButtonBackground"
                                                                     Fill="White"
                                                                     Opacity="0" />
                                                            <TextBlock x:Name="PART_Text"
                                                                       Margin="0,0,0,1"
                                                                       HorizontalAlignment="Center"
                                                                       VerticalAlignment="Center"
                                                                       FontSize="10"
                                                                       Foreground="White"
                                                                       Text="X" />
                                                        </Grid>
                                                        <ControlTemplate.Triggers>
                                                            <Trigger Property="IsMouseOver" Value="True">
                                                                <Setter TargetName="PART_ButtonBackground" Property="Opacity" Value="0.8" />
                                                                <Setter TargetName="PART_Text" Property="Foreground" Value="Black" />
                                                            </Trigger>
                                                        </ControlTemplate.Triggers>
                                                    </ControlTemplate>
                                                </Button.Template>
                                            </Button>
                                        </StackPanel>
                                    </Border>
                                </DataTemplate>
                            </ItemsControl.ItemTemplate>
                        </ItemsControl>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ComboBox.Style>
</ComboBox>
public partial class MultiSelectionComboBox : ComboBox
{
    #region fields, dependencies, command and constructor
    private ListBox listBox;
    private ItemsControl itemsControl;
    private CheckBox checkBox;

    public static readonly DependencyProperty ASLSelectedItemsProperty = DependencyProperty.Register("ASLSelectedItems", typeof(ObservableCollection<object>), typeof(MultiSelectionComboBox), new PropertyMetadata(null));
    public static readonly DependencyProperty ASLDisplayMemberPathProperty = DependencyProperty.Register("ASLDisplayMemberPath", typeof(string), typeof(MultiSelectionComboBox), new PropertyMetadata("Description"));

    public MultiSelectionComboBox()
    {
        InitializeComponent();
    }

    public DelegateCommand<object> UnselectCommand { get; private set; }
    public DelegateCommand CheckAllCommand { get; private set; }

    public ObservableCollection<object> ASLSelectedItems
    {
        get { return (ObservableCollection<object>)GetValue(ASLSelectedItemsProperty); }
        set { SetValue(ASLSelectedItemsProperty, value); }
    }

    public string ASLDisplayMemberPath
    {
        get { return (string)GetValue(ASLDisplayMemberPathProperty); }
        set { SetValue(ASLDisplayMemberPathProperty, value); }
    }
    #endregion

    private void CheckAll()
    {
        if (checkBox.IsChecked == true)
        {
            listBox.SelectAll();

        }
        else
        {
            listBox.UnselectAll();
        }
    }

    private void GetControls()
    {
        checkBox = Template.FindName("checkBox", this) as CheckBox;
        listBox = Template.FindName("lstBox", this) as ListBox;
        itemsControl = Template.FindName("itemsControl", this) as ItemsControl;
    }

    private bool bug = true;
    private void ListBoxOnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        e.AddedItems.Cast<object>().Where(item => !ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Add(p));
        e.RemovedItems.Cast<object>().Where(item => ASLSelectedItems.Contains(item)).ForEach(p => ASLSelectedItems.Remove(p));
        checkBox.IsChecked = (listBox.ItemsSource as IList).Count == listBox.SelectedItems.Count;
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        GetControls();
        SetControls();
        UnselectCommand = new DelegateCommand<object>(p => listBox?.SelectedItems.Remove(p));
        CheckAllCommand = new DelegateCommand(CheckAll);
    }

    private void SetControls()
    {
        listBox.DisplayMemberPath = ASLDisplayMemberPath;
        itemsControl.DisplayMemberPath = ASLDisplayMemberPath;
    }

    private void Test_OnLoaded(object sender, RoutedEventArgs e)
    {
        (sender as TextBlock)?.SetBinding(TextBlock.TextProperty, ASLDisplayMemberPath);
    }
}
公共部分类MultiSelectionComboBox:ComboBox
{
#区域字段、依赖项、命令和构造函数
私有列表框列表框;
私有项控件项控件;
私有复选框;
public static readonly dependencProperty ASLSelectedItemsProperty=dependencProperty.Register(“ASLSelectedItems”、typeof(ObservableCollection)、typeof(MultiSelectionComboBox)、new PropertyMetadata(null));
公共静态只读DependencyProperty ASLDisplayMemberPathProperty=DependencyProperty.Register(“ASLDisplayMemberPath”、typeof(字符串)、typeof(多选组合框)、new PropertyMetadata(“说明”);
公共多选组合框()
{
初始化组件();
}
public DelegateCommand UnselectCommand{get;private set;}
public DelegateCommand CheckAllCommand{get;private set;}
公共可观测集合ASLSelectedItems
{
获取{return(observetecollection)GetValue(aslselecteditemsprroperty);}
set{SetValue(ASLSelectedItemsProperty,value);}
}
公共字符串ASLDisplayMemberPath
{
获取{return(string)GetValue(ASLDisplayMemberPathProperty);}
set{SetValue(asldisplaymberpathProperty,value);}
}
#端区
私有void CheckAll()
{
如果(checkBox.IsChecked==true)
{
listBox.SelectAll();
}
其他的
{
listBox.UnselectAll();
}
}
私有控件()
{
checkBox=Template.FindName(“checkBox”,this)作为复选框;
listBox=Template.FindName(“lstBox”,this)作为listBox;
itemsControl=Template.FindName(“itemsControl”,this)作为itemsControl;
}
私有布尔错误=真;
private void ListBoxOnSelectionChanged(对象发送者,选择ChangedEventArgs e)
{
e、 AddedItems.Cast().Where(item=>!ASLSelectedItems.Contains(item)).ForEach(p=>ASLSelectedItems.Add(p));
e、 RemovedItems.Cast().Where(item=>ASLSelectedItems.Contains(item)).ForEach(p=>ASLSelectedItems.Remove(p));
checkBox.IsChecked=(listBox.itemsource as IList).Count==listBox.SelectedItems.Count;
}
应用程序模板()上的公共重写无效
{
base.OnApplyTemplate();
GetControls();
SetControls();
UnselectCommand=newdelegateCommand(p=>listBox?.SelectedItems.Remove(p));
CheckAllCommand=新的DelegateCommand(CheckAll);
}
私有void SetControls()
{
listBox.DisplayMemberPath=ASLDisplayMemberPath;
itemsControl.DisplayMemberPath=ASLDisplayMemberPath;
}
私有无效测试\u已加载(对象发送器,路由目标e)
{
(发送方为TextBlock)?.SetBinding(TextBlock.TextProperty,ASLDisplayMemberPath);
}
}
视图模型

public class MainWindowViewModel
{
    public ObservableCollection<Model> Models { get; set; }
    public ObservableCollection<object> SelectedModels { get; set; }

    public MainWindowViewModel()
    {
        Models = new ObservableCollection<Model>()
        {
            new Model() {FirstName = "Amelia", Age = 0},
            new Model() {FirstName = "Bruno", Age = 5},
            new Model() {FirstName = "Colin", Age = 47},
            new Model() {FirstName = "Daniel", Age = 32},
            new Model() {FirstName = "Iza", Age = 28},
            new Model() {FirstName = "James", Age = 23},
            new Model() {FirstName = "Simon", Age = 23}
        };
        SelectedModels = new ObservableCollection<object> {Models.FirstOrDefault() };
    }
}
公共类MainWindowViewModel
{
公共可观测集合模型{get;set;}
公共ObservableCollection SelectedModels{get;set;}
公共主窗口视图模型()
{
模型=新的ObservableCollection()
{
新模型(){FirstName=“Amelia”,年龄=0},
新模型(){FirstName=“Bruno”,Age=5},
新模型(){FirstName=“Colin”,年龄=47},
新模型(){FirstName=“Daniel”,年龄=32},
新模型(){FirstName=“Iza”,Age=28},
新模型(){FirstName=“James”,年龄=23},
新模型(){FirstName=“Simon”,年龄=23}
};
SelectedModels=new ObservableCollection{Models.FirstOrDefault()};
}
}
现在的问题是,如果在用户控件内(列表