【问题标题】:WPF custom listbox selectdItem with buttonWPF自定义列表框selectedItem与按钮
【发布时间】:2013-03-23 20:35:47
【问题描述】:

我设法构建了一个自定义列表框,其中每个项目都从数据库中加载,在堆栈面板中显示名称和姓氏。在这 2 个文本框之后应该有一个按钮,它正确绑定到 ViewModel 的 ICommand。 该按钮正确调用了正确的方法,但它不会删除 selectedPerson,因为该对象为空。

这是列表框的 WPF

<Style x:Key="CustomHorizontalListbox" TargetType="{x:Type ListBox}">
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
    <Setter Property="BorderThickness" Value="0" />
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Border BorderBrush="Black" BorderThickness="2">
                <StackPanel Orientation="Horizontal" Width="200" Margin="0,0,0,0">
                    <TextBox Text="{Binding FirstName}" Width="60" BorderThickness="0" Margin="0" IsReadOnly="True"></TextBox>
                    <TextBox Text="{Binding LastName}" Width="100" BorderThickness="0" Margin="0" IsReadOnly="True"></TextBox>
                    <Button Width="20" Height="20" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.OnDeletePatient}" CommandParameter="{Binding}"></Button>
                </StackPanel>
                </Border>
            </DataTemplate>
        </Setter.Value>                
    </Setter>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <WrapPanel></WrapPanel>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是 ViewModel 上的相对方法

private void DeletePatient()
    {
        patientsManager.DeletePatient(SelectedPatient);
        ListOfPatients = new ObservableCollection<RealPatient>(patientsManager.GetAllRealPatients());
        SelectedPatient = null;
    }

这就是自定义列表框包含在视图中的方式

<ListBox Grid.Row="2" Grid.Column="3" Style="{StaticResource CustomHorizontalListbox}" ItemsSource="{Binding ListOfPatients}" SelectedItem="{Binding SelectedPatient}">

    </ListBox>

所以问题是 DeleteMethod 处的断点显示 SelectedPatient = null..

我错过了什么?...即使我点击列表项而不是单个按钮,SelectedPatient 也不会改变

谢谢

【问题讨论】:

  • 尝试将 Mode=TwoWayUpdateSourceTrigger=PropertyChanged 添加到您的 SelectedItem-Binding。
  • 不...它不起作用...
  • 试试我的解决方案,对我来说效果很好..
  • 不行,还是不行……!!
  • 我发布了我的整个工作示例应用程序。

标签: wpf data-binding listbox


【解决方案1】:

这是我的完整示例应用程序:

    <Window.Resources>
    <Style x:Key="CustomHorizontalListbox" TargetType="{x:Type ListBox}">
        <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="ItemTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Border BorderBrush="Black" BorderThickness="2">
                        <StackPanel Orientation="Horizontal" Width="200" Margin="0,0,0,0">
                            <TextBox Text="{Binding FirstName}" Width="60" BorderThickness="0" Margin="0" IsReadOnly="True"></TextBox>
                            <TextBox Text="{Binding LastName}" Width="100" BorderThickness="0" Margin="0" IsReadOnly="True"></TextBox>
                            <Button Width="20" Height="20" Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=DataContext.OnDeletePatient}" CommandParameter="{Binding}"></Button>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel></WrapPanel>
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type ListBoxItem}">
        <Style.Resources>
            <Storyboard x:Key="OnGotKeyboardFocus1">
                <BooleanAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="{x:Null}" Storyboard.TargetProperty="(Selector.IsSelected)">
                    <DiscreteBooleanKeyFrame KeyTime="00:00:00" Value="True"/>
                </BooleanAnimationUsingKeyFrames>
            </Storyboard>
        </Style.Resources>
        <Style.Triggers>
            <EventTrigger RoutedEvent="Keyboard.GotKeyboardFocus">
                <BeginStoryboard Storyboard="{StaticResource OnGotKeyboardFocus1}"/>
            </EventTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>
<Window.DataContext>
    <Regions:ViewModel/>
</Window.DataContext>
<Grid>
    <ListBox Style="{StaticResource CustomHorizontalListbox}" ItemsSource="{Binding ListOfPatients}" SelectedItem="{Binding SelectedPatient}" >

    </ListBox>
</Grid>

这里是我在 ViewModel 中的 SelectedPatient 属性的定义:

    private Patient _SelectedPatient;
    public Patient SelectedPatient
    {
        get { return _SelectedPatient; }
        set
        {
            _SelectedPatient = value;
            NotifyPropertyChanged(m => m.SelectedPatient);
        }
    }

每当您单击列表框项目行的任何位置时,都会设置您选择的项目。

我希望我能更深入地解释为什么会这样,但我在 MSDN 论坛中找到了它: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/1642c5f9-e731-4a3d-9eed-0f574d90d925 我为我正在使用的应用程序使用了该修复程序。

【讨论】:

  • 它工作得很好,但是如果有人对此有解释可以写在某处或提供一些有用的链接吗?...
  • 这是一种基于事件触发器设置属性的时髦方式。这是我的理解,当检测到此 ListBoxItem (GotKeyboardFocus) 的键盘焦点事件时,然后启动一个动画,在完成后将您的 TargetProperty=Selector.IsSelected 设置为 true。类似帖子:stackoverflow.com/questions/942548/…
猜你喜欢
  • 1970-01-01
  • 2012-05-24
  • 2015-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多