WPF中的自定义ListBox

时间:2013-06-20 04:07:49

标签: c# .net wpf

我正在尝试在WPF中为聊天Messenger创建自定义ListBox控件。我使用椭圆来显示在线/离线用户。椭圆将显示在左侧,一些文本显示在ListBoxItem的中心。

我想根据某个变量将椭圆填充属性设置为红色/绿色。

这就是我所做的:

<ListBox Name="myList" HorizontalAlignment="Left" Height="232" Margin="117,74,0,0" VerticalAlignment="Top" Width="207">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel>
                        <Ellipse Name="ellipse" Fill="Red" DockPanel.Dock="Left">
                            <Ellipse.Triggers>
                                <Trigger Property="{Binding Online}" Value="True">
                                    <Setter TargetName="ellipse" Property="Ellipse.Fill" Value="Green"/>
                                </Trigger>
                            </Ellipse.Triggers>
                        </Ellipse>
                        <TextBlock Text="{Binding text}"></TextBlock>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>            
        </ListBox>

并在代码中:

myList.Items.Add(new { text="Hello",Online="True"  });

我收到错误

Cannot find the static member 'FillProperty' on the type 'ContentPresenter'.

我在这里做错了什么?

4 个答案:

答案 0 :(得分:4)

显然这是错误的:Property="{Binding Online}"(阅读文档?)

此外,您应该使用Style触发器,无需设置TargetName,并且需要考虑precedence,并使用Setter作为默认值值。

答案 1 :(得分:3)

你实际上误导了WPF的一些问题。

  1. 绑定触发器上的属性不起作用。你必须使用DataTrigger insrants of Triggers。
  2. 实时触发任何控件。大多数时候都不行。所以请选择Styles。
  3. 在模板中创建椭圆时,请确保已为其创建足够的尺寸。这样用户就可以看到了。
  4. 试试这个。

    <Window.Resources>
        <Style x:Key="elstyle" TargetType="Ellipse">
            <Setter Property="Height" Value="5"/>
            <Setter Property="Width" Value="5"/>
            <Setter Property="Fill" Value="Red"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding Online}" Value="true">
                    <Setter Property="Fill" Value="Green"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    
    </Window.Resources>
    <Grid>
        <ListBox x:Name="myList" HorizontalAlignment="Left" Height="232" Margin="117,74,0,0" VerticalAlignment="Top" Width="207">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <DockPanel>
                        <Ellipse Name="ellipse" Margin="5" DockPanel.Dock="Left" Style="{DynamicResource elstyle}">
                        </Ellipse>
                        <TextBlock Text="{Binding Name}"></TextBlock>
                    </DockPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
    

    代码背后。

      public MainWindow()
            {
                Random r = new Random();
                InitializeComponent();
                for (int i = 0; i < 10; i++)
                {
                    myList.Items.Add(new { Name = "Name" + i.ToString(), Online = Convert.ToBoolean(r.Next(-1, 1)) });
                }
            }
    

答案 2 :(得分:1)

您需要通过Setter而不是XAML设置初始颜色。有关详细信息,请参阅此问题:Change the color of ellipse when mouse over

答案 3 :(得分:0)

您的XAML中存在一些问题

  • 设置Ellipse
  • 的大小
  • 您需要使用Style代替Ellipse.Triggers
  • 如果您因某种情况无法在XAML中更改Fill,请设置Style颜色

这里是您的问题的工作示例

            <DataTemplate>

                <!--<DockPanel> juste because i like StackPanel-->
                    <StackPanel Orientation="Horizontal">

                    <!--<Ellipse Name="ellipse" Fill="Red" DockPanel.Dock="Left">-->
                    <Ellipse Name="ellipse" Width="15" Height="15">

                        <!--<Ellipse.Triggers>-->
                        <Ellipse.Style>
                            <Style TargetType="Ellipse">      

                                <Setter Property="Fill" Value="Red"/>

                                <Style.Triggers>

                                    <!--<Trigger Property="{Binding Online}" Value="True">-->
                                    <DataTrigger Binding="{Binding Online}" Value="True">
                                        <Setter Property="Fill" Value="LimeGreen"/>
                                    </DataTrigger>

                                </Style.Triggers>

                            </Style>
                        </Ellipse.Style>

                    </Ellipse>
                    <TextBlock Text="{Binding text}"/>

                </StackPanel>
            </DataTemplate>