【问题标题】:When does XAML binding get evaluated?何时评估 XAML 绑定?
【发布时间】:2011-10-12 14:39:07
【问题描述】:

我如何知道 XAML 绑定何时被评估?

-有没有我可以挂钩的方法/事件?

-有没有办法强制这些绑定进行评估?

我有以下 XAML,其中包含 3 个图像,每个图像都有不同的来源:

<Window...>
<Window.Resources>
    <local:ImageSourceConverter x:Key="ImageSourceConverter" />
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Image x:Name="NonBindingImage" Grid.Column="0" Source="C:\Temp\logo.jpg" />
    <Image x:Name="XAMLBindingImage" Grid.Column="1" Source="{Binding Converter={StaticResource ImageSourceConverter}}" />
    <Image x:Name="CodeBehindBindingImage" Grid.Column="2" />
</Grid>
</Window>

这是 XAML 中引用的转换器:

public class ImageSourceConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        BitmapImage image = new BitmapImage();

        image.BeginInit();
        image.StreamSource = new FileStream(@"C:\Temp\logo.jpg", FileMode.Open, FileAccess.Read);
        image.EndInit();

        return image;
    }

这是窗口代码:

...
public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        Binding binding = new Binding { Source = CodeBehindBindingImage, Converter = new ImageSourceConverter() };
        BindingOperations.SetBinding(CodeBehindBindingImage, Image.SourceProperty, binding);

        object xamlImageSource = XAMLBindingImage.Source; // This object will be null
        object codeBehindImageSource = CodeBehindBindingImage.Source; // This object will have a value

        // This pause allows WPF to evaluate XAMLBindingImage.Source and set its value
        MessageBox.Show("");
        object xamlImageSource2 = XAMLBindingImage.Source; // This object will now mysteriously have a value
    }
}
...

当使用相同转换器通过代码设置绑定时,它会立即计算。

当通过 XAML 和转换器设置绑定时,它会将评估推迟到稍后的时间。我在代码中随机调用 MessageBox.Show,它似乎导致 XAML 绑定源进行评估。

有什么办法可以解决这个问题吗?

【问题讨论】:

  • 我认为您不需要“修复”它,因为它没有损坏。它在需要时而不是之前进行评估。
  • 我将问题修改为没有争议,但如果您 A) 将列索引 1 的宽度更改为自动并且 B) 调用 Measure/Arrange,XAMLBindingImage.Source 仍然为空。我的理解是 Measure/Arrange 需要元素的大小才能正确布局(以及如何知道带有 null 源的 am Image 的大小)。
  • 为了完整起见,在窗口的构造函数中额外调用 this.UpdateLayout() 也不会加载图像源。

标签: c# wpf xaml binding


【解决方案1】:

它将在渲染时进行评估。由于 MessageBox.Show() 导致 UI 线程启动,因此将在显示消息框之前对其进行评估。

尝试连接到 WPF 窗口的 Loaded 方法并在那里运行您需要执行的操作。

编辑:根据http://blogs.msdn.com/b/mikehillberg/archive/2006/09/19/loadedvsinitialized.aspx,加载的事件应该在数据绑定之后运行。如果失败了,我建议考虑使用 Dispatcher 来排队您的代码以使用 Invoke 在 UI 线程上运行

【讨论】:

  • 我试过这个:将代码放在 Loaded 中仍然会为 XAML 中的绑定集产生空结果。我的困惑来自为什么这两个绑定(代码和 xaml)在评估时表现不同
  • 谢谢,当您将线程的优先级设置为 DispatcherPriority.Loaded 时,调用 Dispatcher.BeginInvoke 有效。然而,这似乎仍然很奇怪,因为 Measure() 和 Arrange() 似乎清楚地表明它们将评估上面示例中基于转换器的绑定。
  • 用 DispatcherPriority.Loaded 对 Dispatcher.BeginInvoke 投赞成票
猜你喜欢
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多