绑定不适用于PropertyChanged

时间:2015-12-12 23:59:05

标签: c# wpf

我尝试使用xaml将属性绑定到SplashScreen中的TEXTBLOCK。文本块应显示属性的内容。 Handler类具有属性" Shares",在splashscreen的xaml代码中我编写了这段代码:

<UserControl
x:Class="DXApplication3.WaitScreen"
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:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"   
xmlns:local="clr-namespace:DXApplication3"
mc:Ignorable="d"
d:DataContext="{x:Static dx:SplashScreenViewModel.DesignTimeData}">
<UserControl.Resources>
    <local:Handler x:Key="Shares"/>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Height="455" Width="859">
    <Grid x:Name="Splash" Width="450" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0">
        <Grid x:Name="Back">
            <Border Background="Black" CornerRadius="3" Opacity="0.15"/>
            <Border CornerRadius="2" Margin="-200,2,-201,-257" Background="White"/>
        </Grid>
        <Image x:Name="Logotype" DockPanel.Dock="Right" Source="../DXSplashScreen/DTILogo.png" Stretch="None"
                   HorizontalAlignment="Right" RenderTransformOrigin="0.5,0.5" Margin="0,24,0,51" Width="253" >
            <Image.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform X="-413" Y="-55"/>
                </TransformGroup>
            </Image.RenderTransform>
        </Image>
        <Grid x:Name="Content_Area" Margin="12">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <dx:WaitIndicator Content="Loading..." DeferedVisibility="true" Margin="0,120,0,-52" Grid.RowSpan="4">
                <dx:WaitIndicator.ContentTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Please Wait" FontSize="20"/>
                            <TextBlock Text="ShareAnalyzer is running..."/>
                        </StackPanel>
                    </DataTemplate>
                </dx:WaitIndicator.ContentTemplate>
            </dx:WaitIndicator>
            <DockPanel x:Name="Footer" Grid.Row="3" Margin="-181,115,205,-91">
                <TextBlock x:Name="TextHeader" TextWrapping="Wrap" Text="Analyzed shares" Opacity="1" Foreground="#FF2D2D2D" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,2,0,-2" FontSize="16" FontWeight="Bold" RenderTransformOrigin="0.5,0.5">
                    <TextBlock.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform X="2" Y="28"/>
                        </TransformGroup>
                    </TextBlock.RenderTransform>
                </TextBlock>
                <TextBlock x:Name="SharesHeader" TextWrapping="Wrap" Text="{Binding Source={StaticResource Shares}, Path=Shares, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Opacity="1" Foreground="#FF2D2D2D" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,4,-87,1" FontSize="13.333" Width="124">
                    <TextBlock.RenderTransform>

我将名为(SharesHeader)的文本块绑定到Handler.cs中的属性Shares

 class Handler : INotifyPropertyChanged
{
    private string _shares;
    public event PropertyChangedEventHandler PropertyChanged;
    public string Shares
    {
        get { return _shares; }
        set
        {
            _shares = value;
            NotifyPropertyChanged("Shares");
        }
    }
    protected virtual void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChangedEventHandler propertyChanged = PropertyChanged;
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

}

SplashScreen应该在我单击MainWindow.cs中的按钮时启动。但问题是,在sart之后,flashscreen中的文本块是空的。

有人能帮帮我吗? 感谢

1 个答案:

答案 0 :(得分:2)

问题是您绑定到静态资源(您命名为-i),但正在更改其他属性(根据注释中的代码,名为Shares)。< / p>

所以你要定义这个:

handler

并将其绑定为:

<UserControl.Resources>
  <local:Handler x:Key="Shares"/>
</UserControl.Resources>

但改变了这一点:

<TextBlock x:Name="SharesHeader" Text="{Binding Source={StaticResource Shares}, Path=Shares, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /*... */ >

因此,不像现在这样创建新实例,而是使用您已通过XAML创建的实例,并更改其private void button_Click(object sender, RoutedEventArgs e) { DXSplashScreen.Show<WaitScreen>(); handler = new Handler(); handler.Shares = "Test 1"; } 属性,如:

Shares

(this.Resources["Shares"] as Handler).Shares = "Test 1"; 是您的窗口(或this,或您在哪里定义资源)对象。如您所见,检查空值。

加成

正如其他人在评论中所说的那样,将事件变量复制到本地变量的整个过程就是“冻结”它,所以如果其他线程修改了null检查和实际调用之间的事件,你将会工作未经修改的副本。

所以你的:

UserControl

应该是:

if (PropertyChanged != null)
{
    PropertyChangedEventHandler propertyChanged = PropertyChanged;
    propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

但是,如果您使用的是C#6(Visual Studio 2015),则可以使用null条件运算符,它将为您执行相同的操作,并将其更改为:

PropertyChangedEventHandler propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
    propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}