Метод измерения Silverlight не работает должным образом в зависимости от объекта привязки данных? - PullRequest
1 голос
/ 11 марта 2011

ОБНОВЛЕНИЕ II Проблема была решена .Спасибо.


Для простого механизма предварительного просмотра печати Silverlight мой XAML выглядит следующим образом (отрывок):

<Grid>
   <TextBlock Text="{Binding IntroText}" />
    <ItemsControl ItemsSource="{Binding DataItems}"
                    x:Name="DataItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding}"
                            TextWrapping="Wrap"
                            Margin="0,2" />
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
    <TextBlock Text="{Binding OutroText}" />
</Grid>

Я хочу убедиться, что все помещается на странице, поэтомуУ меня есть простой метод:

public bool FitsOnPrintPage(Size pageDimensions)
{
    Measure(new Size(pageDimensions.Width, Double.PositiveInfinity));

    return
        DesiredSize.Height <= pageDimensions.Height &&
        DesiredSize.Width <= pageDimensions.Width;
}

Теперь у нас есть странная проблема, которую я не могу объяснить:

Связанная коллекция DataItems является общим object списком.При использовании простых строк метод Measure(...) работает как положено и возвращает правильно вычисленный DesiredSize.Пока что все работает.

Однако, если у вас есть простой объект, подобный этому ...

public class DataItem
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
}

... и при изменении привязки TextBlock на <TextBlock Text="{Binding Path=Value1}"... результирующее представлениеидентичен, однако метод Measure(...) не возвращает ожидаемые значения, высота элементов всегда равна нулю.Также не работает: оставьте Text Binding и переопределите метод DataItem s ToString().Просмотр работает, измерение - нет.

Затем я пытался принудительно пересчитать, используя такие методы, как InvalidateMeasure() или UpdateLayout() на DataTemplate или на всей странице, но безуспешно.

МожетВы объясняете это?

ОБНОВЛЕНИЕ
Интересно: я прикрепил простой пользовательский ValueConverter к привязке TextBlock только для отладки.Когда объект string привязан, я вижу, что Measure(...) запускает привязку - сначала она разрешается (я вижу, как отладчик входит в ValueConverter), а затем измеряется.Но при привязке пользовательского класса, как описано выше, Measure(...) не касается Binding, я вхожу в точку останова ValueConverter «позже». (Нужно выяснить, когда именно)

Помогает ли это вам как-нибудь?

Ответы [ 3 ]

0 голосов
/ 11 марта 2011

Вот код от http://silverpdf.codeplex.com/

Может быть, это поможет вам, но вы должны изменить его, чтобы сделать его пригодным для использования.

private System.Windows.Size CalculeteSize()
{
  var s = new System.Windows.Controls.StackPanel()
  {
    VerticalAlignment = System.Windows.VerticalAlignment.Center,
    HorizontalAlignment = System.Windows.HorizontalAlignment.Center
  };
  var fs = FontPool.GetFontStream(Typeface.FontFamily.Source);
  s.Children.Add(new System.Windows.Controls.TextBlock
  {
    Text = Text,
    FontSource = new FontSource(fs),
    FontSize = EmSize,
    FontFamily = Typeface.FontFamily,
    FontStretch = Typeface.FontStretch,
    FontStyle = Typeface.FontStyle,
    FontWeight = Typeface.FontWeight,
  });
  s.Measure(new System.Windows.Size(double.MaxValue, double.MaxValue));

  var aw = s.DesiredSize.Width;
  var ah = s.DesiredSize.Height;
  var size = new System.Windows.Size(aw, ah);

  return size;
}
0 голосов
/ 15 марта 2011

Решено

Проблема заключалась в том, что элементы управления страницы создавались и вычислялись первыми и добавлялись в элемент управления отображением после генерации, поскольку я хотел избежать частых обновлений пользовательского интерфейса.Нечто подобное было даже , предложенное Ai_boy , который пытался решить проблему с помощью независимого Grid элемента управления - к сожалению, это оказалось обманчивым подходом.Только после того, как сгенерированный элемент управления страницей был добавлен в визуальное дерево, он автоматически разрешает привязки, что приводит к правильному измерению размера.

Надеюсь, это кому-нибудь поможет.

0 голосов
/ 11 марта 2011

Ответ прост .. вы работаете не «серебряным светом»

В Silverligth - не имеет значения, подходит ли строка к ширине экрана или нет, если строка не подходит, просто установите TextBlock.Wrap на Wrap ...

У вас проблема с этим "старым мышлением" ...

Но если вы так сильно этого хотите, попробуйте это:

var ContainerGrid = new Grid(); // create grid at runtime

// !!! it's important for controlToMesure.Parent property to be NULL, if it's not
// !!! then temporary remove controlToMesure from parent container...
ContainerGrid.Children.Add(controlToMesure); // add control that you want to mesure

ContainerGrid.Measure(new Size(pageWidth, pageHeight));
ContainerGrid.Arrange(new Rect(0, 0, pageWidth, pageHeight));
ContainerGrid.UpdateLayout();

var size = ((FrameworkElement)ContainerGrid.Children[0]).DesiredSize;
...