我的一个用户在尝试通过我的C#应用程序打开Excel文件时遇到问题.
当我从我的机器运行它时,一切正常,它适用于其他用户.我不是Excel互操作专家所以希望你们可以帮助我.
以下是它的设置方式:
我将我的应用程序的引用添加到Microsoft.Office.Interop.Excel.dll,版本10.0.4504.0(我相信是Excel 2002).在我的机器上,我安装了Excel 2007.在我的代码中,我尝试打开这样的工作表:
using Microsoft.Office.Interop
...
Microsoft.Office.Interop.Excel.ApplicationClass _excelApp = new Microsoft.Office.Interop.Excel.ApplicationClass();
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = _excelApp.Workbooks.Open(workbookPath, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", false, false, 0, true, false, false);
Microsoft.Office.Interop.Excel.Sheets excelSheets = excelWorkbook.Worksheets;
Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item(1);
Run Code Online (Sandbox Code Playgroud)
我将用户版本记录为Excel 9.0(即2000).用户获得的错误是:
Exception='System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Microsoft.Office.Interop.Excel.Workbooks.Open(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object …Run Code Online (Sandbox Code Playgroud) 我不确定这是否只是默认的WPF选项卡控件行为或是否有一种方法可以禁用它.
我有一个tab控件定义如下:
<TabControl TabStripPlacement="Left"
Background="Transparent"
ItemsSource="{Binding Path=AvailableProducts}"
SelectedValuePath="Name"
SelectedValue="{Binding Path=SelectedProduct, Mode=TwoWay}">
Run Code Online (Sandbox Code Playgroud)
AvailableProducts是产品列表.例如:
Foo
Bar
Baz
Run Code Online (Sandbox Code Playgroud)
最初,SelectedProduct为null但是当显示选项卡控件时,它会自动选择Foo.我想要的是根本没有选择标签.
选项卡控件是否总是选择第一个选项卡?
UPDATE
我添加了一些示例代码,显示了我所描述的内容.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TabControl SelectedIndex="1">
<TabItem Header="TAB 1">
<Button>TEST</Button>
</TabItem>
<TabItem Header="TAB 2">
<TabControl TabStripPlacement="Left"
Background="Transparent"
ItemsSource="{Binding Path=AvailableProducts}"
SelectedValuePath="Name"
SelectedValue="{Binding Path=SelectedProduct, Mode=TwoWay}"/>
</TabItem>
</TabControl>
</Grid>
</Window>
using System.Collections.Generic;
namespace WpfApplication1
{
public partial class MainWindow
{
private List<Product> _availableProducts = new List<Product>();
public MainWindow()
{
SelectedProduct = null;
InitializeComponent();
_availableProducts.Add(new Product("Foo"));
_availableProducts.Add(new …Run Code Online (Sandbox Code Playgroud) 使用Infragistics XamDataGrid我遇到了一种情况,我只想在设置了某个属性时才应用Style.但是,我认为这更像是一个普通的WPF /样式问题,而不是xamDataGrid特有的.
以下风格是我目前使用的.它将checkBox添加到记录选择器区域:
<Style TargetType="{x:Type igDP:RecordSelector}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type igDP:RecordSelector}">
<CheckBox x:Name="HeaderCheckBox"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsChecked="{Binding Path=DataItem.IsChecked}">
</CheckBox>
<ControlTemplate.Triggers>
<Trigger Property="IsFilterRecord" Value="True">
<Setter TargetName="HeaderCheckBox" Property="Visibility" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsAddRecord" Value="True">
<Setter TargetName="HeaderCheckBox" Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
TargetType是RecordSelector.如果记录是筛选行或添加记录行,我不想显示复选框.
我想改变它,以便如果记录是添加记录行(IsAddRecord == true),那么根本不应用该样式.我希望添加记录行保留其默认样式.
这可能吗?
我打算第一次按照MVVM模式编写一个WPF应用程序,但对我来说并不是很清楚.假设视图有一个"保存"按钮,当它被命中时,我需要保存我的数据的当前状态(模型).这将通过向SOAP服务发送SOAP消息来完成.
在我的MVVM设置中,这些SOAP请求/响应处理程序是否存在?每当按下保存按钮时,视图模型是否会自动调用SOAP?视图模型是否应该通知模型保存自己?也许它是另一种方式,与MVVM完全分开?
我的想法是(至少在这种特定情况下)视图模型将处理它,因为它需要在视图中禁用保存按钮,直到当前保存请求完成.
这看起来很简单,但我无法让它发挥作用.
我有一个单行文本框,有很多文本.我想要发生的是,只要文本框获得焦点,它就会滚动到文本的末尾,以便它进入视图,光标在最后准备好接受新文本.
在文本框的GotFocus事件中,我调用textBox.ScrollToEnd().看起来所有这一切都是将光标移动到文本框的末尾,但实际上并没有将结束视图.
我错过了什么?
我试图遵循在单元测试中使用WPF Dispatcher的建议,以便运行我的nUnit测试.
当我按如下所示编写单元测试时,它可以工作:
[Test]
public void Data_Should_Contain_Items()
{
DispatcherFrame frame = new DispatcherFrame();
PropertyChangedEventHandler waitForModelHandler = delegate(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Data")
{
frame.Continue = false;
}
};
_myViewModel.PropertyChanged += waitForModelHandler;
Dispatcher.PushFrame(frame);
Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试使用DispatcherUtil的建议,它不起作用:
[Test]
public void Data_Should_Contain_Items()
{
DispatcherUtil.DoEvents();
Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}
public static class DispatcherUtil
{
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void DoEvents()
{ …Run Code Online (Sandbox Code Playgroud) 我知道yield关键字表示它出现的方法是迭代器.我只是想知道它是如何工作的List<T>.AddRange.
我们使用下面的例子:
static void Main()
{
foreach (int i in MyInts())
{
Console.Write(i);
}
}
public static IEnumerable<int> MyInts()
{
for (int i = 0; i < 255; i++)
{
yield return i;
}
}
Run Code Online (Sandbox Code Playgroud)
因此,在每个yield之后的上述示例中,在foreach循环中返回一个值Main并将其打印到控制台.
如果我们改为Main:
static void Main()
{
var myList = new List<int>();
myList.AddRange(MyInts());
}
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?是否AddRange为yield语句返回的每个int调用,还是在添加整个范围之前以某种方式等待所有255个值?
我正在处理一个大型应用程序的线程问题(获得跨线程异常).有没有办法找到创建特定控件的线程名称/ ID?
当我尝试将新控件添加到控件的控件集合时,会发生错误.我不能真正创建一个小的,可重复的样本,所以我会尽可能地描述它.
我有一个位于表单上的主控件,称之为_mainControl.在它的构造函数中,我实例化了另一个控件的实例,例如
ChildControl _childControl = new ChildControl();
Run Code Online (Sandbox Code Playgroud)
现在_childControl存在但我还没有将它添加到_mainControls集合中.
最终,_mainControl会收到一个我应该添加控件的事件通知.在事件处理程序中,我检查是否.InvokeRequired,如果是,我调用处理程序,如下所示:
AddControlEventHander(...)
{
if(InvokeRequired)
{
BeginInvoke(new MethodInvoker(AddControlEventHander);
return;
}
Controls.Add(_childControl);
}
Run Code Online (Sandbox Code Playgroud)
Controls.Add总是抛出异常("跨线程操作无效:从创建它的线程以外的线程访问控件'_item').
现在,我不明白这是怎么回事.我在创建_mainControl的同一个线程上创建了_childControl.当我在调试时查看线程窗口时,当我调用Control.Add时,当添加_childControl时,当前线程名称/ id是相同的.但是,让我最困惑的是来自_mainControl的以下调用:
InvokeReuqired == false;
_childControl.InvokeRequired == false;
_childControl._item.InvokeRequired == true; //I made _item public just to try this and it returns true!
Run Code Online (Sandbox Code Playgroud)
怎么可能?_childControl是否有可能在一个线程上创建,而其子项以某种方式在另一个线程上创建?所有_childControl的子节点都是在初始化期间创建的,正如通常所做的那样.
如果有人对可能发生的事情有任何提示/建议,请告诉我.
谢谢.
编辑:
如果有人有兴趣,我会发现发生了什么.我很好奇如何在一个线程上创建一个控件,并且它是在另一个线程上创建的子节点,即使InitializeComponent都是在同一个线程上完成的.所以,我发现了使用类似于Charles建议的代码创建孩子的线程.一旦我知道了,我至少知道要关注哪个主题.然后我打破了子控件的OnHandleCreated事件并找到了问题.
我不知道的一件事是控件的句柄是在控件首次可见时创建的,而不是在创建控件时创建的.因此,没有控件的线程试图将其可见性设置为true.所以我添加了一个检查以查看InvokeRequired并认为这样做会有所帮助.但是,我真的没想到的是调用InvokeRequired会创建控件的句柄(如果它还没有创建)!这实际上导致在错误的线程上创建控件,并且始终为InvokeRequired返回false.我通过触摸控件的Handle属性来解决这个问题,以便在调用InvokeRequired之前创建它.
谢谢你的帮助:)
我正在创建一个基本视图模型类.ViewModelBase是一个抽象类,我想定义我希望所有其他派生视图模型实现的属性.
其中一个属性是ObservableCollection:
public abstract ObservableCollection<???> Items { get; set; }
Run Code Online (Sandbox Code Playgroud)
从此基类派生的类将定义不同类型的Items(ObservableCollection<Person>,ObservableCollection<Car>).
如果我将ObservableCollection类型设置为objectViewModelBase,则需要在派生类中执行大量不同的转换才能使其工作.
这是正确的方法吗?
我试图修改WpfToolkit的DropDownButton样式,以便允许我设置背景颜色.
这是DropDownButton的默认样式:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:chrome="clr-namespace:Xceed.Wpf.Toolkit.Chromes"
xmlns:conv="clr-namespace:Xceed.Wpf.Toolkit.Core.Converters"
xmlns:local="clr-namespace:Xceed.Wpf.Toolkit">
<conv:InverseBoolConverter x:Key="InverseBoolConverter" />
<LinearGradientBrush x:Key="PopupDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFA3AEB9" Offset="0" />
<GradientStop Color="#FF8399A9" Offset="0.375" />
<GradientStop Color="#FF718597" Offset="0.375" />
<GradientStop Color="#FF617584" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="PopupBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Offset="0" Color="#FFffffff" />
<GradientStop Offset="1" Color="#FFE8EBED" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<Style TargetType="{x:Type local:DropDownButton}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Padding" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:DropDownButton}">
<Grid x:Name="MainGrid" …Run Code Online (Sandbox Code Playgroud) c# ×7
wpf ×6
mvvm ×2
.net ×1
dispatcher ×1
excel ×1
foreach ×1
infragistics ×1
interop ×1
list ×1
nunit ×1
unit-testing ×1
wpf-controls ×1
wpftoolkit ×1
xamdatagrid ×1