我们正在控制子类中进行自定义绘制OnRender.此绘图代码基于外部触发器和数据.因此,每当触发器触发时,我们都需要根据该数据重新呈现控件.我们要做的是找出如何强制控件重新渲染但不经过整个布局传递.
如上所述,我所看到的大多数答案都围绕着使Visual无效的布局无效,这会迫使新的测量并安排非常昂贵的通行证,特别是对于像我们这样非常复杂的视觉树.但同样,布局不会改变,VisualTree 也不会改变.唯一能做的就是外部数据的呈现方式不同.因此,这严格来说是纯粹的渲染问题.
同样,我们只是在寻找一种简单的方法来告诉控件它需要重新执行OnRender.我见过一个"黑客"在您创建一个新的DependencyProperty,并用你刚才设置的时候要刷新的控制一定的价值"AffectsRender"注册它,但我更感兴趣的是发生了什么事情的默认实现内那些属性:他们所谓的影响那种行为.
好了,它看起来像没有任何这样的呼叫,因为即使是AffectsRender国旗还是引起内部安排通(按照以下CodeNaked的答案),但我已经张贴,显示了内置行为,以及一个工作-第二个答案周围禁止你的布局传递代码从一个简单的可空大小作为标志运行.见下文.
自定义WPF控件会覆盖OnRender.该方法从自定义数据生成并显示路径.数据提供程序使用依赖项属性绑定.当数据发生变化时,依赖属性会为事件注册.此事件又调用InvalidateVisual().
但是,在InvalidateVisual()之后,并不总是调用OnRender.
我们使用Prism Framework和Region functionallity.所讨论的控件嵌入在这样的区域中,该区域被激活和停用.但是,只要区域处于活动状态,Control的属性"IsVisible"就为true.但是,当调用InvalidateVisual()时,OnRender方法不会被调用...
什么可以阻止OnRender方法被调用?
我想在WPF中绘制时间表.它应该基本上由3个矩形组成.
它应该看起来像这样(使用XAML硬编码): 时间轴
大的白色矩形应填充所有可用空间,绿色矩形表示在时间轴上发生的事件的开始和持续时间.
表示此模型的模型是TimeLineEvent类,它具有TimeSpan开始和时间跨度持续时间,以表示事件何时开始以及持续多长时间(以滴答或秒或其他为单位).还有一个TimeLine类,它有一个ObservableCollection,用于保存时间轴上的所有事件.它还有一个TimeSpan持续时间,表示时间轴本身的长度.
我需要做的是能够根据它们的持续时间和开始动态绘制时间轴上的事件(绿色矩形),以及它们之间的比率,以便绘制与事件发生时间和持续时间相对应的事件.时间轴上可以有多个事件.
到目前为止,我的方法是创建一个仅包含canvas元素的TimeLine.xaml文件.在代码隐藏文件中,我重写了OnRender方法来绘制这些矩形,这些矩形适用于硬编码值.
在MainWindow.xaml中,我创建了一个datatemplate并将数据类型设置为TimeLine:
<DataTemplate x:Key="TimeLineEventsTemplate" DataType="{x:Type local:TimeLine}">
<Border>
<local:TimeLine Background="Transparent"/>
</Border>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
尝试了不同的设置,但不确定我要做的是说实话.然后我有一个stackpanel,它包含一个列表框,它使用我的datatemplate和绑定TimeLines,它是一个ObservableCollection,包含TimeLine对象,在我的MainWindow代码隐藏中.
<StackPanel Grid.Column="1" Grid.Row="0">
<ListBox x:Name="listBox"
Margin="20 20 20 0"
Background="Transparent"
ItemTemplate="{StaticResource TimeLineEventsTemplate}"
ItemsSource="{Binding TimeLines}"/>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
这会在我创建新的时间轴对象时绘制新的时间轴,如下所示: 时间轴
这个问题是它没有正确渲染绿色矩形,为此我需要知道白色矩形的宽度,这样我就可以使用不同持续时间的比率转换到一个位置.问题似乎是在调用OnRender方法时width属性为0.我已经尝试重写OnRenderSizeChanged,如下所示:在WPF中如何在实际渲染之前获取控件的渲染大小? 我在调试打印中看到OnRender首先被调用,然后是OnRenderSizeChanged然后我通过调用this.InvalidateVisual()来让OnRender再次运行.在覆盖中.我可以得到的所有宽度属性仍然总是0虽然这很奇怪,因为我可以看到它被渲染并具有大小.还尝试了其他帖子中显示的测量和排列覆盖,但到目前为止还没有能够获得除0以外的值.
那么如何在时间轴上以正确的位置和大小动态绘制矩形呢?
对不起,如果我遗漏了一些明显的东西,我刚刚和WPF一起工作了一个星期,我没有人问.如果您想查看更多代码示例,请与我们联系.任何帮助表示赞赏:).
我有一个包含100个观测值的双变量数据集.我使用了六边形装箱,结果是26个六边形箱.为了保存26个六边形箱中每个的100个观测值的行,我使用了base::attrR中的函数.在下面的代码中,这是在以下位置完成的:
attr(hexdf, "cID") <- h@cID
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建Plotly六边形分箱的交互式R 对象,以便如果用户点击给定的六边形分区,它们将获得分组到该分区中的100个观察的行.我完成了这个目标的一部分.我的MWE如下:
library(plotly)
library(data.table)
library(GGally)
library(hexbin)
library(htmlwidgets)
set.seed(1)
bindata <- data.frame(ID = paste0("ID",1:100), A=rnorm(100), B=rnorm(100))
bindata$ID <- as.character(bindata$ID)
x = bindata[,c("A")]
y = bindata[,c("B")]
h <- hexbin(x=x, y=y, xbins=5, shape=1, IDs=TRUE)
hexdf <- data.frame (hcell2xy (h), hexID = h@cell, counts = h@count)
attr(hexdf, "cID") <- h@cID
pS <- ggplot(hexdf, aes(x=x, y=y, fill = counts, hexID=hexID)) + geom_hex(stat="identity")
ggPS <- ggplotly(pS)
myLength <- length(ggPS[["x"]][["data"]])
for (i in 1:myLength){
item =ggPS[["x"]][["data"]][[i]]$text[1]
if (!is.null(item)) …Run Code Online (Sandbox Code Playgroud) 我想动态画一些东西.以下代码显示了我的OnRender.我正在我的程序中的某个地方设置DrawItem,我需要它.但是,当我打电话给DrawItem =5;我必须打电话时,OnRender会被调用吗?
protected override void OnRender(DrawingContext drawingContext)
{
switch (DrawItem)
{
case 1:
//Draw Item
break;
case 2:
//Draw Item
break;
case 3:
//Draw Item
break;
case 4:
//Draw Item
break;
case 5:
//Draw Item
break;
}
base.OnRender(drawingContext)
}
public int DrawItem { get; set; }
Run Code Online (Sandbox Code Playgroud) 我想检查图像是否已满载.所以我onRendered在模板上使用图像:
模板
<template name="backgroundImage">
<img class="bg blur" src="{{image}}">
</template>
Run Code Online (Sandbox Code Playgroud)
帮手
Template.backgroundImage.helpers({
image: function() {
return '/images/background_1.jpg';
}
});
Run Code Online (Sandbox Code Playgroud)
事件
Template.backgroundImage.onRendered(function() {
console.log('image loaded, start fadeOut on overlay');
});
Run Code Online (Sandbox Code Playgroud)
我现在的问题是,这真的有效吗?不onRendered开火的那一刻,当图像已加载它火只是加载HTML?
我的目标是在图像完全加载后,使用加载动画淡化叠加.用户应该在(!)图像加载后看到页面的内容.
我正在尝试创建自己的图形用户控件,我已经有一个已经在win表单上工作,我正在尝试将其移动到WPF世界中.
我开始学习如何绘图,所以我首先尝试绘制一个填充整个窗口的黑色椭圆,只是为了了解坐标在WPF中是如何工作的.
所以这里是代码,当我运行应用程序时,没有显示任何内容,任何想法我错过了什么?
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
drawingContext.DrawEllipse(Brushes.Black, new Pen(Brushes.Black, 1), new Point(Width / 2, Height / 2), Width / 2, Height / 2);
}
}
Run Code Online (Sandbox Code Playgroud) onrender ×7
wpf ×5
c# ×2
javascript ×2
draw ×1
drawellipse ×1
drawing ×1
htmlwidgets ×1
invalidation ×1
meteor ×1
plotly ×1
prism ×1
r ×1
redraw ×1
timeline ×1
xaml ×1