XAML绑定BitmapImage ViewModel属性 [英] XAML bind BitmapImage ViewModel property

查看:87
本文介绍了XAML绑定BitmapImage ViewModel属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对视图模型类的更新列表框有疑问.我使用Caliburn Micro框架.我的情况是在这里:

I have problem with update listbox from view model class. I use Caliburn Micro framework. My scenario is here:

我在列表框上绑定了bindableCollection类型的属性:

I bind property of type bindableCollection on listbox:

视图模型中的代码:

private BindableCollection<UserInfo> _friends;

public BindableCollection<UserInfo> Friends
{
    get { return _friends; }
    set
    {
        _friends= value;
        NotifyOfPropertyChange(()=>Friends);
    }
}

在视图模型中,我创建了伪造的服务方法,将新的新数据作为列表返回,并使用此数据更新了在列表框上绑定的属性Friends.

In view model I create fake service method wich return new fresh data as List and with this data I update property Friends which is bind on listbox.

我每3秒在调度程序计时器滴答事件中调用一次伪造的服务方法.

I call fake service method in dispatcher timer tick event every 3 seconds.

 private static UserInfo FakeUser()
        {
            var user = new UserInfo
            {
                Age = "16",
                Emphasis = true,
                IdUser = "11542",
                IsBlocked = false,
                IsFriend = true,
                LocationInfo = new Location
                {
                    CityName = "TN",
                    IdCity = 123456,
                    IdRegion = 1246,
                    RegionName = "TN",
                },
                StatusInfo = new Status
                {
                    IdChat = 12,
                    IsLogged = true,
                    LastLogin = "153151",
                    IsChating = true,
                    RoomName = "Car",
                },
                ProjectStatusInfo = new ProjectStatus(),
                IsIamFriend = true,
                PlusInfo = new Plus(),
                ProfilePhoto = new BitmapImage(new Uri("http://pokec.azet.sk/vanes90?i9=1f104a294997", UriKind.RelativeOrAbsolute))

            };

            return user;
        }

        private static IEnumerable<UserInfo> GetFakeFriends()
        {
            var list = new List<UserInfo>();

            for (int i = 0; i < 20; i++)
            {
                list.Add(FakeUser());
            }

            return list;
        }

        private void DispatcherTimer_Tick(object sender, EventArgs eventArgs)
        {
            if (_isExecuting)
                return;
            _isExecuting = true;
            new System.Threading.Tasks.Task(() =>
            {
                var freshFriends = GetFakeFriends();

                Execute.OnUIThread((System.Action)(() =>
                {
                    Friends.Clear();
                    foreach (var freshFriend in freshFriends)
                    {
                        Friends.Add(freshFriend);

                    }
                }));
            }).Start();

            _isExecuting = false;
        }

    }

如果我不在列表框上应用任何样式,则效果很好.

If I don’t apply any style on listbox, it works good.

查看:

<Grid>
    <ListBox Name="Friends"
             Grid.Row="2" 
             Margin="4,4,4,4">
    </ListBox>
</Grid>

如果我应用某种样式来绑定列表框上UserInfo的属性ProfilePhoto(BitmapeImage的类型).

If I apply some style in which I bind property ProfilePhoto (typeof BitmapeImage) from UserInfo on listbox.

样式在这里:

        <Style x:Key="friendsListStyle" TargetType="{x:Type ListBox}">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid Name="RootLayout">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="0.3*"></ColumnDefinition>
                                <ColumnDefinition Width="*"></ColumnDefinition>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="60"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Image Margin="4,4,4,2" Source="{Binding Path=ProfilePhoto}" Grid.Column="0"/>
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>

我收到此错误:

Must create DependencySource on same Thread as the DependencyObject.

   at System.Windows.Markup.XamlReader.RewrapException(Exception e, Uri baseUri)
   at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter)
   at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter)
   at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField)
   at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren)
   at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate)
   at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container)
   at System.Windows.FrameworkElement.ApplyTemplate()
   at System.Windows.FrameworkElement.MeasureCore(Size availableSize)
   at System.Windows.UIElement.Measure(Size availableSize)
   at System.Windows.Controls.Border.MeasureOverride(Size constraint)

如果我在列表框/列表框项目上创建其他样式,则在仅绑定字符串或bool属性的情况下,效果很好.

If I make another style on listbox / listbox item, in wich I bind only string or bool properties it works good.

仅当绑定bitmapImage属性时,我才有问题.

I have problem only if bind bitmapImage property.

BitmapImage属性的初始化方式为:

BitmapImage property is init as:

ProfilePhoto = new BitmapImage(new Uri("http://pokec.azet.sk/vanes90?i9=1f104a294997", UriKind.RelativeOrAbsolute))

URI是图片的URL或文件的路径.

URI is url of picture or path to the file.

怎么了?感谢您的帮助和建议.

What is wrong? Thank for help and advice.

样式很好,只有当我不使用另一个线程中的方法调用刷新数据时,它才起作用.

Style is good, it work only if I don’t refresh data with method call in another thread.

推荐答案

如果要在UI线程以外的任何线程上创建BitmapImage,则可以解释此问题.您可以冻结BitmapImage以确保可以从任何线程对其进行访问:

If you're creating the BitmapImage on any thread other than the UI thread, that would explain this issue. You can freeze the BitmapImage to ensure it is accessible from any thread:

var bitmapImage = new BitmapImage(...);
bitmapImage.Freeze();

这篇关于XAML绑定BitmapImage ViewModel属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆