我有一个具有自定义控件的自定义面板,这些控件应该像RibbonButton那样调整大小,即随着可用大小的变化,我应该删除/添加一个标题,调整内部图片的大小,等等。
此外,自定义控件是无外观的控件,即在样式中定义了UI/Template,我使用触发器更新模板元素。
通过使用继承的附加属性(我指UI继承,如DataContext),我将面板中的大小设置与各个控件进行通信。
当我在面板中做我的多通MeasureOverride()时,当我调用child.Measure()时,就好像我的项目总是一样大小的!尽管我更改了继承的附加属性(它确实在控件内部更新!)为了清楚起见,我的内部控件不调整大小,但当我更改继承的属性时,它们会更改它们的UI模板(改为更小的版本)。
知道如何成功地实现、RibbonButon、和类似行为的行为吗?
发布于 2014-07-03 09:59:12
我可能没有在继承的属性上设置正确的元数据选项!因为我设法让它工作,调整他们!
为了清晰起见,我将在下面我能写的最简单的示例下面发布(我以前没有这样做,即使是最简单的示例,也是相当长的!)
Size123Control.cs
public class Size123Control : Control
{
static Size123Control()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Size123Control), new FrameworkPropertyMetadata(typeof(Size123Control)));
}
}Size123Panel.cs
public class Size123Panel : Panel
{
public static int GetSize123(DependencyObject obj) { return (int)obj.GetValue(Size123Property); }
public static void SetSize123(DependencyObject obj, int value) { obj.SetValue(Size123Property, value); }
public static readonly DependencyProperty Size123Property = DependencyProperty.RegisterAttached(
"Size123", typeof(int), typeof(Size123Panel),
new FrameworkPropertyMetadata(3,
FrameworkPropertyMetadataOptions.Inherits
| FrameworkPropertyMetadataOptions.AffectsMeasure
| FrameworkPropertyMetadataOptions.AffectsParentMeasure
| FrameworkPropertyMetadataOptions.AffectsArrange
| FrameworkPropertyMetadataOptions.AffectsParentArrange
));
protected override Size ArrangeOverride(Size finalSize)
{
double hTot = 0, h = 0, x = 0, xMax = 0;
foreach (UIElement child in Children)
{
var cs = child.DesiredSize;
if (x > 0 && x + cs.Width > finalSize.Width)
{
hTot += h;
x = 0;
h = cs.Height;
}
else
{
if (cs.Height > h)
h = cs.Height;
}
child.Arrange(new Rect(new Point(x, hTot), cs));
x += cs.Width;
if (x > xMax)
xMax = x;
}
return new Size(xMax, hTot + h);
}
protected override Size MeasureOverride(Size availableSize)
{
Func<Size> measure = () =>
{
double hTot = 0, h = 0, x = 0, xMax = 0;
foreach (UIElement child in Children)
{
child.Measure(availableSize);
var cs = child.DesiredSize;
if (x > 0 && x + cs.Width > availableSize.Width)
{
hTot += h;
x = 0;
h = cs.Height;
}
else
{
if (cs.Height > h)
h = cs.Height;
}
x += cs.Width;
if (x > xMax)
xMax = x;
}
return new Size(xMax, hTot + h);
};
SetSize123(this, 3);
var s1 = measure();
if (s1.Width <= availableSize.Width && s1.Height <= availableSize.Height)
return s1;
SetSize123(this, 2);
var s2 = measure();
if (s2.Width <= availableSize.Width && s2.Height <= availableSize.Height)
return s2;
SetSize123(this, 1);
var s3 = measure();
return s3;
}
}generic.xaml
<Style TargetType="{x:Type local:Size123Control}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:Size123Control}">
<Border x:Name="MAIN" Width="48" Height="48" Background="Red" BorderThickness="1" BorderBrush="LightGray"/>
<ControlTemplate.Triggers>
<Trigger Property="local:Size123Panel.Size123" Value="2">
<Setter TargetName="MAIN" Property="Background" Value="Green"/>
<Setter TargetName="MAIN" Property="Width" Value="32"/>
<Setter TargetName="MAIN" Property="Height" Value="32"/>
</Trigger>
<Trigger Property="local:Size123Panel.Size123" Value="1">
<Setter TargetName="MAIN" Property="Background" Value="Blue"/>
<Setter TargetName="MAIN" Property="Width" Value="16"/>
<Setter TargetName="MAIN" Property="Height" Value="16"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>main.xaml
<local:Size123Panel>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
<local:Size123Control/>
</local:Size123Panel>https://stackoverflow.com/questions/24532923
复制相似问题