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

