C# Excel/VSTO:仅当直接绑定到互操作时出现错误0x80028018。-提供的属性

C# Excel/VSTO:仅当直接绑定到互操作时出现错误0x80028018。-提供的属性,c#,excel,wpf,vsto,C#,Excel,Wpf,Vsto,当我尝试使用此测试应用程序设置工作表的Name属性时,由于0x80028018错误,它无法工作 当我更改第一个文本框中的值并单击tab按钮时,什么也没有发生,而我希望Sheet1被重命名。在Visual Studio输出窗口中,我可以看到以下错误: System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=Worksheet.Name; DataIte

当我尝试使用此测试应用程序设置工作表的Name属性时,由于0x80028018错误,它无法工作

当我更改第一个文本框中的值并单击tab按钮时,什么也没有发生,而我希望Sheet1被重命名。在Visual Studio输出窗口中,我可以看到以下错误:

System.Windows.Data Error: 8 : Cannot save value from target back to source. 
BindingExpression:Path=Worksheet.Name; DataItem='ViewModel' (HashCode=35209123); target element is 'TextBox' (Name=''); target property is 'Text' (type 'String')
ExternalException:'System.Runtime.InteropServices.ExternalException (0x80028018): Exception of type 'System.Runtime.InteropServices.ExternalException' was thrown.
at System.Windows.Forms.ComponentModel.Com2Interop.Com2PropertyDescriptor.SetValue(Object component, Object value)
at MS.Internal.Data.PropertyPathWorker.SetValue(Object item, Object value)
at MS.Internal.Data.ClrBindingWorker.UpdateValue(Object value)
at System.Windows.Data.BindingExpression.UpdateSource(Object value)'
该应用程序是一个非常基本的WPF应用程序,其ViewModel类包含对工作簿的引用。然后我们有一个绑定到ViewModel的视图(xaml)类

Viewmodel类:
public class ViewModel
{

    public Worksheet Worksheet { get; set; }
    public ViewModel(Worksheet worksheet)
    {
        Worksheet = worksheet;
    }

    public string Name
    {
        get => Worksheet.Name;
        set => Worksheet.Name = value;
    }
}
然后,在视图中,我有一个绑定到工作表的Name属性的TextBox控件。
基本上有两种方法:

<TextBox Text="{Binding Worksheet.Name}"/>
它只保留启动和接线代码。作为一个启动器,我使用了一个带按钮的功能区(设计的,不是xaml)

public partial class Ribbon1
{
    private void Ribbon1_Load(object sender, RibbonUIEventArgs e) { }

    private void button1_Click(object sender, RibbonControlEventArgs e)
    {

        Worksheet myWorksheet = (Worksheet)Globals.ThisAddIn.Application.ActiveSheet;

        ViewModel vm = new ViewModel(myWorksheet);

        UserControl1 view = new UserControl1() { DataContext = vm };

        Form form = new Form();

        ElementHost wpfHost = new ElementHost() { Dock = DockStyle.Fill, Child = view };
        form.Controls.Add(wpfHost);

        form.Show();
    }
}
版本:
  • Visual Studio 2017(英语)
  • Excel 2010(英文)

您链接的文章陈述了以下内容:

大多数Excel对象模型方法和属性都需要指定LCID(区域设置标识符)。如果客户端计算机具有英语版本的Excel,并且当前用户的区域设置配置为其他语言(例如德语或法语),Excel可能会触发“旧格式或无效类型库”异常,错误代码为0x80028018(-2147647512)

它还告诉您将
System.Threading.Thread.CurrentThread.CultureInfo设置为Excel使用的值。最简单的方法是对当前(UI)线程全局执行一次:

Thread.CurrentThread.CurrentCulture=new CultureInfo(Application.LanguageSettings.LanguageID[MsoAppLanguageID.msoLanguageIDUI])
至于发生这种情况的原因,在通过绑定直接调用和从包装器属性调用时,似乎使用了不同的LCID。进行这些调用时,您可能需要检查
Thread.CurrentThread.CurrentCulture
Thread.CurrentThread.CurrentUICulture
属性


以下是有关不同区域性设置的更多背景信息的链接:

简而言之,
CurrentThread.CurrentCulture
是您当前的区域设置(您可以通过控制面板进行更改),
CurrentThread.CurrentUICulture
对应于您安装的Windows语言(您通常无法轻松更改),
CultureInfo.DefaultThreadCurrentCulture
将更改当前的
CurrentThread.CurrentCulture
属性,并为将来的线程设置默认值,最后有一行类似于以下内容,适用于WPF绑定:

FrameworkElement.LanguageProperty.OverrideMetadata(
类型(框架元件),
新框架属性元数据(
XmlLanguage.GetLanguage(
CultureInfo.CurrentCulture.IetfLanguageTag);


当然,您也可以将本地用户区域性更改为Excel使用的区域性(英语)。

您是否尝试在工作表名称($worksheet.name)前面使用美元符号。excel中的美元符号表示您有一个系统表,该表在excel for worksheet中内部使用。您也可以尝试使用$Sheet.Name,这是一个C#应用程序,我应该在哪里添加$sign?美元符号是名称的一部分。所以可能:“$”+sheet.Name行工作表.Name已经起作用了。我尝试在文本框中的名称中添加$,但没有成功。工作表名称中是否有空格。如果是空格,你可能需要放方括号。好的,如果你把你在ThisAddIn_启动事件中说的那一行放进去,它就会起作用。在此之前,我在工作表中检查了getter Thread.CurrentThread.CurrentUICulture返回{en US},而Thread.CurrentThread.CurrentCulture返回{it}。这很奇怪,似乎wpf使用非UI区域性,而非UI代码使用UI设置。似乎很矛盾。我添加了一些更多的背景信息,以便更多地了解这里所涉及的不同层次的文化背景。
<UserControl x:Class="ExcelAddIn12.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:ExcelAddIn12"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
    <StackPanel>
        <!--the non-working solution: -->
        <TextBox Text="{Binding Worksheet.Name}"/>
        <TextBox/>
    </StackPanel>
</UserControl>
public partial class Ribbon1
{
    private void Ribbon1_Load(object sender, RibbonUIEventArgs e) { }

    private void button1_Click(object sender, RibbonControlEventArgs e)
    {

        Worksheet myWorksheet = (Worksheet)Globals.ThisAddIn.Application.ActiveSheet;

        ViewModel vm = new ViewModel(myWorksheet);

        UserControl1 view = new UserControl1() { DataContext = vm };

        Form form = new Form();

        ElementHost wpfHost = new ElementHost() { Dock = DockStyle.Fill, Child = view };
        form.Controls.Add(wpfHost);

        form.Show();
    }
}