我是否需要在物品消失时取消绑定物品以防止内存泄漏?我想我只是有点担心,如果我重新加载并将新模板应用于控件,并且在该模板中存在与外部元素的绑定,是否可以阻止对模板的控制被垃圾收集?
首先,免责声明,我正在使用.net 3.5的virtualizingstackpanel.如果您在将来的版本中有不同的行为,请告诉我.使用listviews设置测试用例相对简单,您可以对其进行测试.
我在virtualizingstackpanel中有一个itemcontainer样式,它将属性IsSelected绑定到viewmodel.
当我在视图模型中选择一个未选择的项目在屏幕外,然后滚动到该项目时,datacontext(viewmode)和实际listviewitem都将IsSelected属性设置为true(预期行为).触发器正确应用于listviewitem突出显示它.
但是,当我取消选择不在视图中的项目的datacontext然后向下滚动直到该项目在视图中时,在到达项目并创建它时,项目的datacontext现在具有IsSelected = true并且listviewitem的IsSelected属性也为true ,因此listviewitem以触发器中的选择矩形结束(不正确的行为).
这几乎就像ListViewItem的属性在创建项目时都被恢复一样(这对我来说很有意义,但是之后他们应该将datacontext的值绑定到项目之后).
但这似乎并没有发生.此外,未能取消选择该项目并向后滚动以找到它.如果我然后选择/取消它,绑定对该项目没有影响.
我在视频模型中选择一个在屏幕外的项目而不是在我取消选择屏幕外的项目时,看不出它为什么会起作用的逻辑原因.在这两种情况下,新创建的项目都需要反弹到viewmodel的当前值.但是,一个有效,另一个没有.
任何帮助或想法将不胜感激.
编辑:好的,所以我只是不能使用回收模式和绑定似乎.谢谢devhedgehog.会给你赏金,但你需要一个答案.我发誓我之前尝试过,但也许我之前没有处理绑定列表视图中的点击事件,所以我打破了物理选择或其他东西的绑定.我确实记得在某一点尝试过这两种模式,但可能还有其他干扰,所以它不起作用.无论如何它现在有效.
既然你提到了它,我想最好避免保留不必要的代码并继承virtualizingstackpanel而不是虚拟化面板.但我希望能够设置水平滚动范围,这需要我重新实现Iscrollinfo.但是,我无法让virtualizingstackpanel与iscrollinfo进行良好的交互
<ListView
x:Name="TestLV"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Background="Green"
ItemsSource="{Binding Path=AddedItems, Mode=OneWay}"
SnapsToDevicePixels="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
VirtualizingStackPanel.IsVirtualizing="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
Grid.Column ="4"
MouseDown="TestLV_MouseDown"
>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=OneWay}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid
x:Name="SignalGrid"
Background="Transparent"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border
Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
SnapsToDevicePixels="true">
<ContentPresenter
x:Name="PART_Header"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
/>
</Border>
<ItemsPresenter
x:Name="ItemsHost"
Grid.Row="1"
Grid.Column="0"
/>
</Grid> …Run Code Online (Sandbox Code Playgroud) 这是一个非常简单的问题,但我想知道是否有人可以解释第4行实际上在做什么?所以第一行给处理程序一个事件.我真的不知道在什么情况下处理程序将返回null或最后一行的作用.
当你传递处理程序时你的对象和属性发生了变化,它对它们有什么作用?
PropertyChangedEventHandler handler = PropertyChanged; //property changed is the event
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
Run Code Online (Sandbox Code Playgroud)
我假设我使用它来获取此代码,但我想了解它正在做什么.
我记得几周前阅读它有时在模板中不起作用,我最近试图在两个不同的窗口中绑定东西,但是找不到名称声明,所以我认为它是名称空间的本地名称通过设置datacontext来绑定类.但是,当我能够使用绑定元素名称时,我真的很好奇,当我不能使用时,因为它可能会更方便.
编辑:在阅读那篇文章时,我发现这很有趣:
"因此,样式和模板都定义了自己的XAML名称范围,与应用样式或模板的对象树中的任何位置无关."
如果这是真的,那是不是意味着Binding ElementName根本不适用于模板?但是我的模板中的ElementName肯定有一些工作绑定.这是最令人困惑的部分,为什么一些绑定在模板中随机工作而其他绑定没有?它必须有一些尝试解析名称的方法,即使它不在模板或同一个名称范围内
据我所知,调度程序发生在另一个线程中,它负责更新数据绑定,布局等.但是,有没有办法等到调度程序没有更多的项目或至少没有更多的数据绑定?我想确保属性更改已更新其所有组件,并在运行更多代码之前运行依赖属性更改的回调.
编辑:所以我猜这不是必需的,我只是想了解我应该做些什么.我的主要问题是WPF,如果滚动查看器的子项调整大小,滚动查看器会自动更新其范围吗?
但我也很好奇我是否可以等待绑定更新,或者是否有任何保证一个绑定在另一个之前更新?我是否希望编码以使绑定更新的顺序无关紧要?目前我使用依赖属性更改回调来执行各种通常依赖于其他属性更新的东西
如果你有:
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
</Grid>
Run Code Online (Sandbox Code Playgroud)
并将厚度为1的边框放入每个网格中,您将在网格行之间的边框上获得双倍厚度.处理此问题的唯一方法是在边框的每个边缘上指定厚度,或者是否有一些控件会在每个列的网格周围创建边框而没有双倍厚度?
目前正在尝试这样做:
<Border
BorderBrush="Black"
BorderThickness="1"
Margin="19,0,0,0"
Background="LightGray"
>
<Viewbox VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Row="1"
Grid.Column="0"
x:Name="TreeViewHeaderTextBox"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Text="Time"
Foreground="Black"
/>
<TextBlock
Grid.Row="1"
Grid.Column="1"
Text="X"
TextAlignment="Center"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
/>
<TextBlock
Grid.Row="1"
Grid.Column="2"
Text="O"
TextAlignment="Center"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
/>
</Grid>
</Viewbox>
</Border>
Run Code Online (Sandbox Code Playgroud)
但是,我开始对旧代码进行更改,因此这不是双边框的好例子.但是,我也从这个模板中获得了双重边框.
<Border Name="Bd"
Grid.Column="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}" …Run Code Online (Sandbox Code Playgroud) 我按照这里提供的教程:
http://blogs.msdn.com/b/dancre/archive/tags/virtualizingtilepanel/
并且在它们的实现中,它们在virtualizingtilepanel上具有依赖属性,用于跟踪子大小.但是,WPF库的virtualizingstackpanel不要求我将子元素的大小设置为属性.但是,我不明白虚拟化堆栈面板如何在不实例化项目的情况下计算面板中的哪些项目可见.
我认为他们需要一个度量传递才能知道项目容器的大小,但是如果没有首先实例化这些项目,他们怎么知道呢?
我的目标是创建一个包含treeviewitems的面板并对其进行虚拟化,但是遵循virtualizingtilepanel中的示例只允许我虚拟化顶级项目.
我需要改变计算哪些项目可见的方式,但我不知道如何知道哪些项目是可见的而不知道大小并实际实例化项目.
编辑:等待,也许它会立即实例化在treeviewitem内部的对象并使用它们来计算大小?
所以我有一个在这里工作的例子:
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="true">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self},
Path=(Validation.Errors), Converter={StaticResource ValidationConverter}}"
/>
</Trigger>
<Trigger Property="Validation.HasError" Value="false">
<Setter Property="ToolTip"
Value="GraphPenWidth" />
<Setter Property="Background"
Value="Blue"
/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
<TextBox.Text>
<Binding Path="GraphPenWidth" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<DaedalusValidationRules:IntegerValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
Run Code Online (Sandbox Code Playgroud)
但是,有没有办法使用验证规则而不绑定到datacontext?
我正在尝试创建一个通用对话框,我可以将各种验证规则传递给.但是,我发现一段时间后,即使我在xaml中创建验证规则,它也无法正常工作.我读过我可以将TextBox的Text属性绑定到自身,但这不起作用.
但是,当我在ValidationRule中放置一个断点时,我在插入数据时似乎正在调用正确的点.此外,样式似乎有效,因为背景为蓝色.这让我相信Validation.HasError永远不会成为现实或变得真实并且变回如此之快以至于我无法看到变化.
在我输入的每个字母后调用验证规则,但文本框不会更新以显示haserror = true.为什么是这样?
我不允许将财产绑定到自己身上吗?有没有其他方法我可以使用验证规则没有绑定或我只是总是要创建一个额外的属性来绑定?最短的修复只是创建一个额外的文本属性并无意义地绑定它,但我曾希望没有必要.
<TextBox
Margin="3"
Height="25"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Left"
Grid.Column="1"
x:Name="MainTextBox"
>
<TextBox.Text>
<Binding RelativeSource="{RelativeSource Self}" Path="Text" UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<rules:IntegerValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" …Run Code Online (Sandbox Code Playgroud) 这给了我一个错误,说我无法将打包类型分配给未打包类型。我同意右侧是打包类型的数组,但为什么表达式的左侧是未打包类型?
parameter [7:0] lsfr_taps [0 : 7] = {8'd9, 8'd5, 8'd3, 8'h21, 8'd9, 8'd9, 8'd5, 8'd9};
Run Code Online (Sandbox Code Playgroud)
不管怎样,更重要的问题是如何在 Verilog 中初始化多位参数的二维数组?
c# ×9
wpf ×9
xaml ×6
binding ×1
events ×1
forms ×1
memory-leaks ×1
panel ×1
validation ×1
verilog ×1