为什么我的依赖属性会出现异常?

4

我花了几个小时来理解依赖属性(在这个网站上找到了很多有价值的信息)。我写了我的第一个依赖属性,但它的行为不像我想要的那样。有人可以看看我的代码并看看是否能发现问题吗?尝试运行应用程序时,会出现TargetInvocationException异常。

  <Window x:Class="TextEditorMVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:c="clr-namespace:TextEditorMVVM.ViewModel"
    Title="MainWindow" Height="660" Width="621" ResizeMode="CanResize" Background="Gray">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/Resources/Dictionary1.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <c:TextEditorViewModel x:Key="TextEditorViewModel"></c:TextEditorViewModel>
    </ResourceDictionary> 
</Window.Resources>
<Border CornerRadius="10" BorderThickness="12" Background="#FF505050">
    <Border.BorderBrush>
        <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
            <GradientStop Color="LightGray" Offset="1" />
            <GradientStop Color="Gray" Offset="0" />
        </LinearGradientBrush>
    </Border.BorderBrush>
    <StackPanel DataContext="{StaticResource TextEditorViewModel}">
    <Menu Height="auto" Background="Transparent" Foreground="White">
        <MenuItem Width=" auto" Height="auto" Header="_File" VerticalAlignment="Center">
            <MenuItem Header="_New" Command="{Binding CreateNewTabCommand}"></MenuItem>
            <MenuItem Header="_Open" Command="{Binding OpenFileCommand}"></MenuItem>
            <MenuItem Header="_Save" Command="{Binding SaveFileCommand}"></MenuItem>
            <MenuItem Header="_Close" Command="{Binding CloseTabCommand}"></MenuItem>
            <MenuItem Header="_Print" Command="{Binding PrintCommand}"></MenuItem>
            <MenuItem Header="_Exit" Command="{Binding }"></MenuItem>
        </MenuItem>
        <MenuItem Width=" auto" Height="auto" Header="_Edit" VerticalAlignment="Center">
            <MenuItem Header="_Cut" Command="ApplicationCommands.Cut"></MenuItem>
            <MenuItem Header="_Copy" Command="ApplicationCommands.Copy"></MenuItem>
            <MenuItem Header="_Paste" Command="ApplicationCommands.Paste"></MenuItem>
        </MenuItem>
        <MenuItem Width=" auto" Height="auto" Header="_Help" VerticalAlignment="Center">
            <MenuItem Header="_Call Mikael" Command="{Binding }"></MenuItem>
            <MenuItem Header="_Call Semyon" Command="{Binding }"></MenuItem>
            <MenuItem Header="_Cry" Command="{Binding }"></MenuItem>
        </MenuItem>
        <Expander Header="Autosave" VerticalAlignment="Center" Foreground="White">
            <StackPanel Orientation="Horizontal">
                <CheckBox VerticalAlignment="Center" IsChecked="{Binding IsChecked, Mode=TwoWay}"></CheckBox>
                <TextBox Width="40" Height="20" Margin="4" ></TextBox>
                    <Label VerticalAlignment="Center" Foreground="White">seconds</Label>
            </StackPanel>
        </Expander>
    </Menu>
        <c:TransparentTb IsTransparent="False" Text="Why aren't you working????">
        </c:TransparentTb>
    <TabControl x:Name="_tabControl" ItemsSource="{Binding TestTab}" SelectedItem="{Binding SelectedTab}" Background="Transparent" BorderThickness="0">
        <TabControl.ItemContainerStyle>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="{Binding Title}"/>
                    <Setter Property="Style" Value="Transparent"/>
                    <Setter Property="Content" Value="{Binding InputText}"/>
                </Style>
        </TabControl.ItemContainerStyle>
    </TabControl>
</StackPanel>
</Border>

class TransparentTb : TextBlock
{
    static TransparentTb()
    {

    }


    {
        get { return (bool) GetValue(IsTranparentProperty); }
        set { SetValue(IsTranparentProperty, value); }
    }

    // Using a DependencyProperty as the backing store for IsTranparent.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty IsTranparentProperty =
        DependencyProperty.Register("IsTransparent", typeof (bool), typeof (TransparentTb),
                                    new UIPropertyMetadata(false, TransparentTb.IsTransparentPropertyChanged,
                                                           TransparentTb.IsTransparentCoerce, false)); 


    private static void IsTransparentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TransparentTb inst = (TransparentTb) d;

        if ((bool)e.NewValue == true)
        {
            inst.Background = Brushes.Transparent;
        }
        else inst.Background = Brushes.Black;
    }

    private static object IsTransparentCoerce(DependencyObject d, object value)
    {
        return value;
    }
}

2
请尽可能提供异常的堆栈跟踪,这样我们就可以更好地了解错误的上下文。 - competent_tech
无论您的异常在哪里被捕获和显示,都可以从异常中显示出 StackTrace 属性。这里有更多信息: http://msdn.microsoft.com/en-us/library/system.exception.stacktrace.aspx - competent_tech
谢谢提供链接,我在我的代码中使用了try catch,但是我有点不确定在依赖属性中应该放置try catch,因为似乎没有必要。这样做是否正确? - Iris Classon
2
当您在调试器下运行应用程序时,应该会弹出一个包含异常详细信息的弹出框。点击底部的“查看详细信息”(在操作下方),并查看其中的信息。您可能想要打开innerexception属性并复制其中包含的堆栈跟踪属性。 - Russell Troywest
2
同样重要的是,TargetInvocationException 几乎总是表示在执行过程中在其他地方(例如在另一个线程上)抛出并未处理的不同异常(由最外层异常的 InnerException 属性表示)。因此,查找 InnerException 及其堆栈跟踪也是明智的选择。 - Adam Maras
显示剩余4条评论
1个回答

4

将这行Xaml代码改为...

<Setter Property="Style" Value="Transparent"/>

变成...

<!-- <Setter Property="Style" Value="Transparent"/> -->
(即将其注释掉) 这样做可以避免异常。 你正在设置样式,这需要引用对象树中已经定义的东西,比如{静态资源透明}。 内部异常是“未设置对象引用...”,这表明构造函数无法按照编码的方式找到对“Transparent”的引用。请注意,异常在TransparentTb已经构造后抛出。你可以通过设置断点来证明这一点。 我还检查了你的TransparentTb代码,它可以正常工作。罪魁祸首是你的TabItem样式Setter。

谢谢,问题解决了。那行代码本来就不应该在那里 :) 很高兴我的第一个依赖属性起作用了!:D - Iris Classon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接