WPF列表框可以绕过另一个组件吗?
我需要在窗口右侧固定一个文本块,在其中设置注释,窗口的其余部分可以是一个列表框,其中填充了可选项。我的问题是,便笺可以是可见的,也可以是不可见的,可选择的项目应该像在Word中一样,将图像和环绕文本设置为“方形” 示例: 已添加 我创建了一个自定义UniformGrid,添加了一个属性NoteRowToSkip,用于在左侧的最后一列中表示要跳过的行。我覆盖ArrangeOverride并添加了所需的跳过行为。 调试看起来值是正确的,但具有与UniformGrid相同的行为WPF列表框可以绕过另一个组件吗?,wpf,listbox,Wpf,Listbox,我需要在窗口右侧固定一个文本块,在其中设置注释,窗口的其余部分可以是一个列表框,其中填充了可选项。我的问题是,便笺可以是可见的,也可以是不可见的,可选择的项目应该像在Word中一样,将图像和环绕文本设置为“方形” 示例: 已添加 我创建了一个自定义UniformGrid,添加了一个属性NoteRowToSkip,用于在左侧的最后一列中表示要跳过的行。我覆盖ArrangeOverride并添加了所需的跳过行为。 调试看起来值是正确的,但具有与UniformGrid相同的行为 publi
public class UniformNoteWrapGrid : Panel
{
private int m_Rows;
private int m_Columns;
public static readonly DependencyProperty NoteRowToSkipProperty = DependencyProperty.Register(nameof(NoteRowToSkip), typeof(int), typeof(UniformGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateNoteRowToSkip);
private static bool ValidateNoteRowToSkip(object o)
{
return (int)o >= 0;
}
public int Columns
{
get => (int)GetValue(ColumnsProperty);
set => SetValue(ColumnsProperty, value);
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register(
"Columns",
typeof(int),
typeof(UniformGrid),
new FrameworkPropertyMetadata(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
ValidateColumns);
private static bool ValidateColumns(object o)
{
return (int)o >= 0;
}
public int Rows
{
get => (int)GetValue(RowsProperty);
set => SetValue(RowsProperty, value);
}
public static readonly DependencyProperty RowsProperty =
DependencyProperty.Register("Rows", typeof(int),
typeof(UniformGrid),
new FrameworkPropertyMetadata(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
ValidateRows);
private static bool ValidateRows(object o)
{
return (int)o >= 0;
}
public int NoteRowToSkip
{
get => (int)GetValue(NoteRowToSkipProperty);
set => SetValue(NoteRowToSkipProperty, value);
}
protected override Size MeasureOverride(Size constraint)
{
UpdateComputedValues();
var childConstraint = new Size(constraint.Width / m_Columns, constraint.Height / m_Rows);
double maxChildDesiredWidth = 0.0;
double maxChildDesiredHeight = 0.0;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
{
var child = InternalChildren[i];
child.Measure(childConstraint);
var childDesiredSize = child.DesiredSize;
if (maxChildDesiredWidth < childDesiredSize.Width)
maxChildDesiredWidth = childDesiredSize.Width;
if (maxChildDesiredHeight < childDesiredSize.Height)
maxChildDesiredHeight = childDesiredSize.Height;
}
return new Size(maxChildDesiredWidth * m_Columns, maxChildDesiredHeight * m_Rows);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
var childBounds = new Rect(0, 0, arrangeSize.Width / m_Columns, arrangeSize.Height / m_Rows);
double xStep = childBounds.Width;
double xBound = arrangeSize.Width - 1.0;
var row = 1;
var column = 1;
foreach (UIElement child in InternalChildren)
{
child.Arrange(childBounds);
if (child.Visibility == Visibility.Collapsed)
continue;
childBounds.X += xStep;
column++;
var testXBound = xBound;
if (IsCellForNote(row, column))
testXBound -= childBounds.Height;
if (!(childBounds.X >= testXBound))
continue;
childBounds.Y += childBounds.Height;
childBounds.X = 0;
row++;
column = 1;
}
return arrangeSize;
}
private bool IsCellForNote(int row, int column)
{
if (row > NoteRowToSkip)
return true;
return column != Columns;
}
private void UpdateComputedValues()
{
m_Columns = Columns;
m_Rows = Rows;
//if (FirstColumn >= m_Columns)
// FirstColumn = 0;
if (m_Rows != 0 && m_Columns != 0)
return;
int nonCollapsedCount = 0;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
{
var child = InternalChildren[i];
if (child.Visibility != Visibility.Collapsed)
nonCollapsedCount++;
}
if (nonCollapsedCount == 0)
nonCollapsedCount = 1;
if (m_Rows == 0)
{
if (m_Columns > 0)
m_Rows = (nonCollapsedCount + (m_Columns - 1)) / m_Columns;
else
{
m_Rows = (int)Math.Sqrt(nonCollapsedCount);
if ((m_Rows * m_Rows) < nonCollapsedCount)
m_Rows++;
m_Columns = m_Rows;
}
}
else if (m_Columns == 0)
m_Columns = (nonCollapsedCount + (m_Rows - 1)) / m_Rows;
}
}
公共类UniformNoteWrapGrid:面板
{
私人国际货币单位行;
私有int m_列;
public static readonly dependencProperty NoteRowToSkipProperty=dependencProperty.Register(name of(NoteRowToSkip)、typeof(int)、typeof(UniformGrid)、new FrameworkPropertyMetadata(0,FrameworkPropertyMetadata options.AffectsMeasure)、ValidateNoterRowtoSkip);
私有静态bool validateNotRowtoskip(对象o)
{
返回值(int)o>=0;
}
公共int列
{
get=>(int)GetValue(ColumnsProperty);
set=>SetValue(ColumnsProperty,value);
}
公共静态只读依赖项属性列属性=
从属属性。寄存器(
“栏目”,
类型(int),
类型(UniformGrid),
新框架属性元数据(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
验证电子柱);
私有静态bool ValidateColumns(对象o)
{
返回值(int)o>=0;
}
公共整数行
{
get=>(int)GetValue(RowsProperty);
set=>SetValue(RowsProperty,value);
}
公共静态只读依赖项属性行属性=
DependencyProperty.寄存器(“行”,类型(int),
类型(UniformGrid),
新框架属性元数据(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
ValidateRows);
私有静态bool ValidateRows(对象o)
{
返回值(int)o>=0;
}
公共int NoteRowToSkip
{
get=>(int)GetValue(NoteRowToSkipProperty);
set=>SetValue(NoteRowToSkipProperty,value);
}
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
updateComputerdValues();
var childConstraint=新大小(constraint.Width/m_列,constraint.Height/m_行);
双maxChildDesiredWidth=0.0;
双maxChildDesiredHeight=0.0;
for(int i=0,count=InternalChildren.count;i=testXBound))
继续;
childBounds.Y+=childBounds.Height;
childBounds.X=0;
行++;
列=1;
}
返回安排大小;
}
私有bool IsCellForNote(int行,int列)
{
如果(行>注释行)
返回true;
返回列!=列;
}
私有void updateComputerdValues()
{
m_列=列;
m_行=行;
//如果(第一列>=m_列)
//第一列=0;
如果(m_行!=0和m_列!=0)
返回;
int noncollecsedCount=0;
for(int i=0,count=InternalChildren.count;i0)
m_行=(非合并计数+(m_列-1))/m_列;
其他的
{
m_Rows=(int)Math.Sqrt(nonCollapsedCount);
if((m_行*m_行)
知道我的代码中有什么不起作用吗
已解决 public class UniformNoteWrapGrid : Panel
{
private int m_Rows;
private int m_Columns;
public static readonly DependencyProperty NoteRowToSkipProperty = DependencyProperty.Register(nameof(NoteRowToSkip), typeof(int), typeof(UniformGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsMeasure), ValidateNoteRowToSkip);
private static bool ValidateNoteRowToSkip(object o)
{
return (int)o >= 0;
}
public int Columns
{
get => (int)GetValue(ColumnsProperty);
set => SetValue(ColumnsProperty, value);
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register(
"Columns",
typeof(int),
typeof(UniformGrid),
new FrameworkPropertyMetadata(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
ValidateColumns);
private static bool ValidateColumns(object o)
{
return (int)o >= 0;
}
public int Rows
{
get => (int)GetValue(RowsProperty);
set => SetValue(RowsProperty, value);
}
public static readonly DependencyProperty RowsProperty =
DependencyProperty.Register("Rows", typeof(int),
typeof(UniformGrid),
new FrameworkPropertyMetadata(
0,
FrameworkPropertyMetadataOptions.AffectsMeasure),
ValidateRows);
private static bool ValidateRows(object o)
{
return (int)o >= 0;
}
public int NoteRowToSkip
{
get => (int)GetValue(NoteRowToSkipProperty);
set => SetValue(NoteRowToSkipProperty, value);
}
protected override Size MeasureOverride(Size constraint)
{
UpdateComputedValues();
var childConstraint = new Size(constraint.Width / m_Columns, constraint.Height / m_Rows);
double maxChildDesiredWidth = 0.0;
double maxChildDesiredHeight = 0.0;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
{
var child = InternalChildren[i];
child.Measure(childConstraint);
var childDesiredSize = child.DesiredSize;
if (maxChildDesiredWidth < childDesiredSize.Width)
maxChildDesiredWidth = childDesiredSize.Width;
if (maxChildDesiredHeight < childDesiredSize.Height)
maxChildDesiredHeight = childDesiredSize.Height;
}
return new Size(maxChildDesiredWidth * m_Columns, maxChildDesiredHeight * m_Rows);
}
protected override Size ArrangeOverride(Size arrangeSize)
{
var childBounds = new Rect(0, 0, arrangeSize.Width / m_Columns, arrangeSize.Height / m_Rows);
double xStep = childBounds.Width;
double xBound = arrangeSize.Width - 1.0;
var row = 1;
var column = 1;
foreach (UIElement child in InternalChildren)
{
child.Arrange(childBounds);
if (child.Visibility == Visibility.Collapsed)
continue;
childBounds.X += xStep;
column++;
var testXBound = xBound;
if (IsCellForNote(row, column))
testXBound -= xStep;
if (!(childBounds.X >= testXBound))
continue;
childBounds.Y += childBounds.Height;
childBounds.X = 0;
row++;
column = 1;
}
return arrangeSize;
}
private bool IsCellForNote(int row, int column)
{
if (row > NoteRowToSkip)
return false;
return column == Columns;
}
private void UpdateComputedValues()
{
m_Columns = Columns;
m_Rows = Rows;
//if (FirstColumn >= m_Columns)
// FirstColumn = 0;
if (m_Rows != 0 && m_Columns != 0)
return;
int nonCollapsedCount = 0;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
{
var child = InternalChildren[i];
if (child.Visibility != Visibility.Collapsed)
nonCollapsedCount++;
}
if (nonCollapsedCount == 0)
nonCollapsedCount = 1;
if (m_Rows == 0)
{
if (m_Columns > 0)
m_Rows = (nonCollapsedCount + (m_Columns - 1)) / m_Columns;
else
{
m_Rows = (int)Math.Sqrt(nonCollapsedCount);
if ((m_Rows * m_Rows) < nonCollapsedCount)
m_Rows++;
m_Columns = m_Rows;
}
}
else if (m_Columns == 0)
m_Columns = (nonCollapsedCount + (m_Rows - 1)) / m_Rows;
}
}
<ItemsControl x:Name="panel">
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type local:NoteItem}">
<TextBlock HorizontalAlignment="Right" TextWrapping="Wrap" Width="50" Height="150" Margin="10"
Text="{Binding Text}" Background="LightBlue">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Visible}" Value="False" >
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
<DataTemplate DataType="{x:Type local:ListItem}">
<TextBlock TextWrapping="Wrap" Width="50" Height="50" Margin="10" Text="{Binding Text}" Background="LightGray"/>
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
public class Item
{
public string Text { get; set; }
}
public class NoteItem:Item
{
public bool Visible{ get; set; }
}
public class ListItem : Item
{
}
public partial class MainWindow : Window
{
ObservableCollection<Item> list = new ObservableCollection<Item>();
public MainWindow()
{
InitializeComponent();
NoteItem note = new NoteItem { Text = "This is a note", Visible = true };
list.Add(note);
for(int i=0;i<20; i++)
list.Add(new ListItem { Text = "This is a list item" });
panel.ItemsSource = list;
}
}