WPF 中的自定义列表框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17205095/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:02:34  来源:igfitidea点击:

Custom ListBox in WPF

c#.netwpf

提问by Tanuj Wadhwa

I am trying to create a custom ListBox control in WPF for a chat Messenger. I am using an ellipse to show the online/offline user. The ellipse is to be displayed on left and some text in center of the ListBoxItem.

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

I want to set the ellipse fill propert to red/green based on some variable.

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

This is what I have done :

这就是我所做的:

<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>

and in the code :

并在代码中:

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

I am getting an error as

我收到一个错误

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

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

What am I doing wrong here?

我在这里做错了什么?

采纳答案by JSJ

you are actually misleading WPF with some of these concerns.

您实际上是在用其中一些问题误导 WPF。

  1. Binding A property on trigger will not work. you have to use DataTrigger insteed of Triggers.
  2. Implementing Trigger on the Fly for any control. most of the times not work. So go with Styles.
  3. While you are creating Ellipse in template make sure you have created enough size for it. So that can be visible to users.
  1. 绑定触发器上的属性将不起作用。您必须使用 DataTrigger 代替触发器。
  2. 为任何控件实现动态触发。大多数时候不起作用。所以选择样式。
  3. 在模板中创建椭圆时,请确保为它创建了足够的大小。这样用户就可以看到。

try this.

尝试这个。

<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>

code behind .

后面的代码。

  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)) });
            }
        }

回答by H.B.

Obviously this is wrong: Property="{Binding Online}"

显然这是错误的: Property="{Binding Online}"

Also you should use a Stylefor triggers, no need to set TargetName, and you need to take precedenceinto consideration, and use a Setterfor the default value.

另外你应该使用aStyle作为触发器,不需要设置TargetName,你需要考虑优先级,并使用aSetter作为默认值。

回答by Oren

You need to set the initial colour via a Setter and not in XAML. For more information and see this question: Change the color of ellipse when mouse over

您需要通过 Setter 而不是在 XAML 中设置初始颜色。有关更多信息,请参阅此问题:鼠标悬停时更改椭圆的颜色

回答by WiiMaxx

there are a few issues in your XAML

您的 XAML 中存在一些问题

  • set the size of your Ellipse
  • you need to use Styleinstead of Ellipse.Triggers
  • set your Fillcolor in your Styleif you wane be able to change it in XAML by some condition
  • 设置你的尺寸 Ellipse
  • 你需要使用Style而不是Ellipse.Triggers
  • 如果您希望能够通过某种条件在 XAML 中更改Fill颜色,请Style在您的颜色中设置颜色

here an working example for your problem

这是您的问题的工作示例

            <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>