2011-01-16 20 views
30

Tengo un problema con el cuadro de lista de actualización de la clase de modelo de vista. Yo uso el marco de Caliburn Micro. Mi escenario es aquí:Enlace XAML propiedad BitmapImage ViewModel

Ato propiedad de tipo bindableCollection el cuadro de lista:

Código de vista del modelo:

private BindableCollection<UserInfo> _friends; 

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

En vista del modelo se crea método de servicio falsa wich regresar nuevos datos frescos como Enumerar y con esta información actualizo la propiedad Friends que está vinculada en listbox.

Llamo a un método de servicio falso en el evento del ticker de despachador cada 3 segundos.

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

    } 

Si no aplico ningún estilo en listbox, funciona bien.

Vista:

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

Si aplico un poco de estilo en el que Ato ProfilePhoto propiedad (typeof BitmapeImage) a partir de información del usuario en el cuadro de lista.

Style está aquí:

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

me sale este error:

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) 

Si hago otro estilo sobre el tema cuadro de lista/cuadro de lista, en wich que sólo obligará a las propiedades de cadena o bool funciona bien .

Tengo un problema solamente si se vincula la propiedad bitmapImage.

propiedad BitmapImage es init como:

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

URI es el URL de la imagen o la ruta de acceso al archivo.

¿Qué pasa? Gracias por ayuda y consejo.

El estilo es bueno, solo funciona si no actualizo los datos con la llamada al método en otro hilo.

Respuesta

71

Si está creando el BitmapImage en cualquier hilo que no sea el de UI, eso explicaría este problema. Se puede congelar la BitmapImage para asegurar que es accesible desde cualquier hilo:

+0

Sr. Boogaart agradecimiento por ayuda, problema está resuelto. –

+5

¡Genial! ¿Cómo te enteraste de ésto? –

+0

Dado que 'BitmapImage' hereda de' System.Windows.Freezable' - "Un Freezable congelado también se puede compartir entre subprocesos, mientras que un Freezable no congelado no puede". - http://msdn.microsoft.com/en-us/library/ms750509(v=vs.110).aspx – codekaizen

Cuestiones relacionadas