TextBlock应居中于位置x(或方向为垂直时为y).我实施了:
TextBlock text = new TextBlock();
// Some code to define text, font, etc. here
// Turn if Orientation is vertical
if (Orientation == Orientation.Vertical)
{
text.RenderTransform = new RotateTransform() { Angle = 270 };
}
// Update, then ActualWidth is set correctly
text.UpdateLayout();
// Position of label centered to given position
double halfWidth = text.ActualWidth / 2;
double x1 = (Orientation == Orientation.Horizontal) ? x - halfWidth : x;
double y1 = (Orientation == Orientation.Horizontal) ? y : y …Run Code Online (Sandbox Code Playgroud) 首先是我开始的代码:
<ribbon:RibbonMenuButton IsEnabled="{Binding ForegroundIsConfigurable}"
SmallImageSource="{Binding Source={StaticResource imageSource},
Path=Source,
UpdateSourceTrigger=OnPropertyChanged}">
Run Code Online (Sandbox Code Playgroud)
虽然这个绑定正在编译并运行良好,但我不满意的原因是imageSource运行时更改.
StaticResource标记扩展:通过查找对已定义资源的引用,为任何XAML属性属性提供值.该资源的查找行为类似于加载时查找,它将查找先前从当前XAML页面的标记以及其他应用程序源加载的资源,并将生成该资源值作为运行中的属性值时间对象.
由于imageSource在运行时期间值的变化,我不得不StaticResource改为DynamicResource.但该属性Source不是依赖属性,因此以下代码将引发运行时错误:
SmallImageSource="{Binding Source={DynamicResource imageSource},
Path=Source,
UpdateSourceTrigger=LostFocus}
Run Code Online (Sandbox Code Playgroud)
出于这个原因,我需要直接绑定动态资源SmallImageSource,这是一个依赖属性:
SmallImageSource="{DynamicResource imageSource}"
Run Code Online (Sandbox Code Playgroud)
这又会引发运行时错误,因为imageSource它的类型是Image.SmallImageSource期望值为type的类型ImageSource.
现在可以建议将数据上下文设置为我的动态资源并适当地绑定属性.如果我这样做,我会杀死IsEnabled另一个属性的绑定DataContext.
据我所知,MultiBinding也不是解决方案,因为这提供了一种机制来将属性绑定到多个源,但不提供针对不同上下文和源的绑定不同属性.
在考虑如何继续下去时,我想到幸运的是,我可以将ImageSource钻井平台变成一个IValueConverter.在我给定的数据上下文中,我RibbonMenuButton有一个具有适当值的字符串值,这实际上也是我的来源ImageSource.
无论如何,我仍然想知道如果我没有其他方法,即如果两个源都在不同的数据上下文中,我将如何解决问题.有什么我没看到的吗?如何通过覆盖DataContext和绑定动态资源的属性来确保不杀死其他绑定?
这imageSource与DrawingImage msdn页面上的XAML示例非常相似.
<Image x:Key="imageSource">
<Image.Source>
<DrawingImage>
...
Run Code Online (Sandbox Code Playgroud) 我有一个抽象类 \xe2\x80\x94 让我们将其命名为Base。该类包含一些属性。此外,我还有另一个类,继承自类Base\xe2\x80\x94 让我们将其命名为Child。Child并不抽象。
我想使用反射访问类中的属性Base,并且仅访问Base.
下面的代码当然是不可能的,因为我无法创建抽象类的实例
\n\nBase base = new Base();\nType type = base.GetType();\nPropertyInfo[] propInfos =\n type.GetProperties(\n BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly\n );\nRun Code Online (Sandbox Code Playgroud)\n\n下面的代码是可能的,但我得到了所有属性,那些定义在Base以及那些定义在Child.
Child child = new Child();\nType type = child.GetType();\nPropertyInfo[] propInfos =\n type.GetProperties(BindingFlags.Instance | BindingFlags.Public);\nRun Code Online (Sandbox Code Playgroud)\n\n如何通过反射获取类的所有属性Base?
在我最近提出的另一个问题中,我被告知使用a CompositeCollection来访问各种来源ListBox.
该示例使用a XmlDataProvider来提供一些虚拟数据.但是,我有一个包含数据的视图模型.
我花了一些时间来绑定ListBox视图模型的数据.最终我明白了,但现在我想明白为什么我以前的方法不起作用.
成功的关键是CollectionViewSource.我最初的尝试是:
<CollectionContainer Collection="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Movies}"/>
<CollectionContainer Collection="{Binding ElementName=Window, Path=DataContext.Movies}"/>
Run Code Online (Sandbox Code Playgroud)
我的想法是找到具有相应DataContext的Window,并绑定数据.你可以通过FindAncestor或通过ElementName,所以我尝试了两个.这对我来说似乎很合乎逻辑,但显然我错了.我运行应用程序时没有看到任何内容.
我还尝试绑定另一个具有数据上下文的控件; 例如StackPanel.
那么,为什么我不用1FindAncestor和ElementName1获取数据,但必须CollectionViewSource明确提供?
这是正在运行的代码.
<StackPanel DockPanel.Dock="Top">
<ListBox ItemTemplateSelector="{StaticResource CustomDataTemplateSelector}">
<ListBox.Resources>
<CollectionViewSource x:Key="ViewSource" Source="{Binding Movies}"/>
</ListBox.Resources>
<ListBox.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource ViewSource}}"/>
<CollectionContainer Collection="{Binding Source={StaticResource MyButtonsData}}"/>
</CompositeCollection>
</ListBox.ItemsSource>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel IsItemsHost="True"
Width="{Binding (FrameworkElement.ActualWidth),
RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
1 …
我已经实现了foreach循环和while循环,它应该创建几乎相同的IL代码.
IL代码(使用C#5的编译器版本12.0.40629生成)确实几乎相同(有些数字的自然例外等),但反编译器能够重现初始代码.
允许反编译器告诉前一个代码块是一个foreach循环而后者代表一个while循环的关键区别是什么?
我在下面提供的反编译代码是使用ILSpy(2.3.1.1855)的最新版本(截至今天)生成的,但我也使用了JustDecompile,.NET Reflector和dotPeek - 没有区别.我没有配置任何东西,我只是安装它们的工具.
原始代码:
using System;
using System.Collections.Generic;
namespace ForeachVersusWhile
{
public class Program
{
public static void Main(string[] args)
{
var x = new List<int> {1, 2};
foreach (var item in x)
{
Console.WriteLine(item);
}
using (var enumerator = x.GetEnumerator())
{
while (enumerator.MoveNext())
{
Console.WriteLine(enumerator.Current);
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
反编译代码:
List<int> x = new List<int>
{
1,
2
};
foreach (int item in x)
{
Console.WriteLine(item);
}
using (List<int>.Enumerator enumerator = x.GetEnumerator())
{
while …Run Code Online (Sandbox Code Playgroud) 我有一个绑定到的组合框List<Person>(ItemsSource在CodeBehind中设置).
<ComboBox Width="120" Background="White" DisplayMemberPath="Name" />
因此,所有人的姓名都被添加到列表中.
因为没有必要在ComboBox中显示每个名称,所以我添加了一个Hide类型的属性bool.如果此属性设置为true,则名称不应显示在组合框中.
但是如何在组合框的绑定中添加一个条件,以便只列出那些不应该被隐藏的人.
编辑:关于答案,我添加了以下代码:
{
List<Person> persons;
...
var collectionView = CollectionViewSource.GetDefaultView(persons);
collectionView.Filter = HideFilter;
}
...
private bool HideFilter(object item)
{
Person p = item as Person;
return p.Hide;
}
Run Code Online (Sandbox Code Playgroud)
但是这会抛出一个TargetInvocationException collectionView.Filter = HideFilter;.
我误解了什么?
我必须设置一个期望获取数组的属性,因此我需要一个类X的实例数组,如下所示:
X[] x = new X[]
{
new X () { Parameter = parameter },
new X () { Parameter = parameter2 }
// ...
}
Run Code Online (Sandbox Code Playgroud)
由于参数是在运行时生成并存储在列表中的,因此应该动态创建实例.我用这个代码得到了我的预期目标
X[] x = new X[list.Count];
for (int i = 0; i < list.Count; i++)
{
x[i] = new X() { Parameter = list.ElementAt(i) }
}
Run Code Online (Sandbox Code Playgroud)
这些线路完成了他们的工作,但是,我对这些线路并不满意.我想改变一些东西,即看起来像伪代码的代码
X[] x = new X[]
{
foreach (var item in list)
{
new X () { Parameter = item }
}
}
Run Code Online (Sandbox Code Playgroud)
但是,此代码不起作用.有没有办法实现这样的代码?
我正在使用第三方工具,在该工具中我收到了 InvalidOperationException(实际上,这最终发生在 PresentationFramework.dll 中):
调用线程无法访问此对象,因为其他线程拥有它。
我尝试了使用 Invoke 的任何变体,包括 BeginInvoke,但没有任何变化。
会话 session = new ThirdPartyTool.Session();
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => session.Open(view)));
使用 Google 时,我只找到建议使用 Invoke 的“解决方案”。好吧,我确实使用 Invoke。
其他问题及其在 stackoverflow 上的相应答案也无济于事。
我还能做些什么来追查真正的原因?
编辑:我再次查看了线程窗口,完整的调用堆栈位于主线程中。AFAIK,这表明调用是多余的。
Edit2:
在调用 open 时不会直接引发错误。ThirdPartyTool 初始化一个列表框,当测量这个列表框时,表示框架中发生错误:

实际异常被包装到 XamlParseException 中。完整的异常细节:
System.Windows.Markup.XamlParseException occurred
HResult=-2146233087
Message=The calling thread cannot access this object because a different thread owns it.
Source=PresentationFramework
LineNumber=0
LinePosition=0
StackTrace:
at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
InnerException: System.InvalidOperationException
HResult=-2146233079
Message=The calling thread cannot access this object because a different thread owns it.
Source=WindowsBase
StackTrace: …Run Code Online (Sandbox Code Playgroud) 我不确定如何真正地将我的问题写成文字,所以让我试着用一个例子来解释它:
假设我的程序在特定操作中遇到了一些奇怪的行为.我已经找到了一些导致这种奇怪行为的代码.禁用此序列时,我不会遇到此行为.不幸的是,我需要这个代码,因为其他东西不起作用.
所以,我接下来要做的是弄清楚当代码摘录处于活动状态时出现异常的原因.
为了更好地理解正在发生的事情,我有时想要运行整个动作,包括"坏代码",有时候没有.然后我可以比较结果,例如UI中发生的事情或我的函数返回的内容.
我想到的第一种方法是在启用代码的情况下运行我的程序,执行我想做的任何事情,然后停止我的程序,注释掉代码,重新编译并再次运行.嗯......听起来很蠢.特别是如果我再次需要打开该代码以查看另一个时间的其他行为,然后再次关闭,打开和关闭等等.
我不能选择使用断点并影响语句顺序或修改值,以便我运行或不运行if-statements,for-loops等.两个例子:
Visual Studio 2012中是否有任何技术允许我将此代码标记为可选,我可以在执行操作之前决定是否要运行此代码序列?我想到if(true|false)了更高层次的事情.
我不是在寻找一个我需要多次重新运行程序的解决方案.在那种情况下,我仍然可以使用简单的方法来简单地注释掉代码#if false.
1请注意,当我需要在特定位置查看特定变量时(如果我没有将值写入输出中),我可能会设置断点,但会再次关闭断点以在一个中运行整个操作走.
c# ×6
wpf ×5
data-binding ×2
arrays ×1
binding ×1
combobox ×1
debugging ×1
decompiling ×1
foreach ×1
invoke ×1
reflection ×1
silverlight ×1