2011-01-16 9 views
30

ビューモデルクラスからのリストボックスの更新に問題があります。私はCaliburn Microフレームワークを使用します。私のシナリオはここにある:XAMLバインドBitmapImage ViewModelプロパティ

私はリストボックスにタイプbindableCollectionのプロパティをバインド:

コードビューモデルから:ビューモデルで

private BindableCollection<UserInfo> _friends; 

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

私は偽のサービスメソッドを作成するには、新しい新鮮なデータを返すWICHリストとこのデータを使用して、リストボックスにバインドされているプロパティFriendsを更新します。

3秒ごとにディスパッチャータイマーのイベントで偽のサービスメソッドを呼び出します。

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; 
     } 

    } 

リストボックスにスタイルを適用しないと、正常に動作します。

ビュー:

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

私はリストボックスの上のUserInfoからプロパティProfilePhoto(typeof演算BitmapeImage)に結合するいくつかのスタイルを適用した場合。

スタイルはここにある:

 <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) 

私はリストボックス/リストボックスの項目に別のスタイルを作る場合は、ウィッヒに私は、文字列またはブール値のプロパティをバインドし、それは良い作品。

bind bitmapImageプロパティの場合にのみ問題があります。

のBitmapImageプロパティは次のようにinitがされています

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

URIは、ファイルへの画像またはパスのURLです。

どうしたのですか?助けとアドバイスをありがとう。

スタイルがうまくいけば、別のスレッドのメソッド呼び出しでデータを更新しないと機能しません。

答えて

71

BitmapImageをUIスレッド以外のスレッドで作成している場合は、この問題が説明されます。 BitmapImageをフリーズして、どのスレッドからもアクセスできるようにすることができます。

+0

Boogaartさん、ありがとうございました。問題が解決しました。 –

+5

素晴らしい!これをどうやって見つけましたか? –

+0

'BitmapImage'は' System.Windows.Freezable'から継承していますから - フリーズされたFreezableはスレッド間で共有できますが、フリーズされていないFreezableでは共有できません。 - http://msdn.microsoft.com/en-us/library/ms750509(v=vs.110).aspx – codekaizen

関連する問題