Я новичок в разработке на c # и WinPhone7 и мне нужно немного советов, если кто-то может быть так добр, поэтому, пожалуйста, извините за мое невежество.
Проблема, с которой я столкнулся, заключается в том, что мне нужно создать представление Grid дляTV Guide, где у вас есть вертикальный список логотипов каналов слева, который прокручивается вверх и вниз, а справа - горизонтальная и вертикальная сетка прокрутки.Горизонтальная прокрутка не перемещает логотипы каналов, которые зафиксированы на экране, но вертикальная сетка прокрутки также прокручивает логотипы, как и следовало ожидать.
Должен ли я продолжать пытаться делать это с использованием XAML и Silverlight или просто делать эточерез XNA?
Я спрашиваю, потому что я пробовал несколько разных методов через Silverlight, чтобы перейти к двум основным проблемам, которые у меня есть:
Производительность
Когда я получаю данные из нашего API с помощью запросов ASync, я создаю фоновый рабочий поток, который анализирует JSON и создает ячейки программы в представлении таблицы «canvas» с помощью Dispatch.Invoke.Поскольку это происходит, постепенная обратная связь отсутствует, все это ждет, пока все не будет сделано, и затем внезапно появляется сетка.Я хотел бы, чтобы ячейки отображались по каналам или по каждой ячейке, не блокируя пользовательский интерфейс, поэтому прокрутка по-прежнему работает хорошо, но, похоже, этого не происходит.
У меня проблемы, как и у любого другогоТакая работа с использованием UIElements выполняется в потоке пользовательского интерфейса, который в WinPhone7 является основным потоком (я полагаю), включая синтаксический анализ XAML или создание / изменение UIElements, даже если они не добавляются ни к чему на экране или не видны.Это означает, что я не могу улучшить вещи, предварительно создав или повторно использовав элементы.
Я попытался сделать как можно больше в рабочем потоке, и лишь крошечная часть работы пользовательского интерфейса отправлялась в поток пользовательского интерфейса, чтобы свести к минимумублокировка, и это, кажется, не помогает.
Память
Ясно, что я не могу создать «программные ячейки» для каждого телевизионного события программы потенциально для сотен (мы поддерживаем более650 каналов) в течение 7 дней, так как телефон очень быстро исчерпает память;поэтому я хотел бы создать виртуальную сетку, в которой ячейки создаются и загружаются в вид холста только для видимой области.
У меня есть две проблемы с этим:
- theБлокировка пользовательского интерфейса при выполнении любой пользовательской работы останавливает любую прокрутку, как описано выше, поэтому создание новых ячеек в фоновом режиме, которые должны быть прокручены, не может происходить без блокировки пользовательского интерфейса
- , так как никакие события прокрутки не отправляются представлением прокрутки,Я экспериментировал с привязкой к полосам прокрутки в обзоре прокрутки, чтобы получить значения смещения, но это не очень хорошо работает, так как он просто обновляется по частям и запускается, поэтому, если вы делаете много прокрутки, ничего не отправляется, пока не останется пауза или OnIdle, я думаю.
Это я все испортил и должен ли я поэтому продолжать, или я делаю что-то, что не могу сделать, и я должен попробовать другой такт, например, делать это через XNA?
Любой советбудет принята с благодарностью.
Редактировать: немного больше информации и пример кода
У меня есть класс Program, который содержит такие вещи, как время начала и заголовок, класс Channel с именем и логотипом и т. Д., А также массив программ.
Когда я получаю свои данные API, я создаюобъект канала и добавить его в массив каналов, затем я добавляю программы в массив программ Каналы.Когда все программы для канала добавлены в массив, я отправляю его в прослушиватель событий ChannelProgrammesComplete для обновления пользовательского интерфейса.
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Visible" ScrollViewer.HorizontalScrollBarVisibility="Visible">
<Canvas x:Name="ProgGrid"
Height="55" Width="393"
VerticalAlignment="Top" HorizontalAlignment="Left">
</Canvas>
</ScrollViewer>
public void ChannelProgrammesComplete( object sender, EventArgs e )
{
var bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += ( doWorkSender, args ) =>
{
Dispatch( (Channel)sender );
};
bw.RunWorkerAsync();
}
private void Dispatch( BackgroundWorker bw, object param )
{
Channel channel = (Channel)param;
int progCount = 0;
foreach( Programme programme in channel.Programmes )
{
double left = ( ( programme.StartSecsFromToday / 60 ) * PixelsPerMinute ); // turn it into seconds
if( progCount == 0 && left < 0 )
{
// If first prog starts before 6am, shrink the cell so it starts at the 6am start point
programme.UIWidth = ( ( programme.Duration - ( ( programme.StartSecsFromToday / 60 ) * -1 ) ) * PixelsPerMinute ) - _cellPadding;
left = 0;
}
else
{
programme.UIWidth = ( programme.Duration * PixelsPerMinute ) - _cellPadding; // Multiply by zoom level which is 3 for now, and take off the amount we use for right margin grid separator
}
Debug.Assert( programme.UIWidth > 0 );
programme.UITop = channel.SortIndex * ( _rowHeight + _cellPadding );
programme.UILeft = left;
programme.UIHeight = _rowHeight;
object[] invokeArgs = new object[ 1 ];
invokeArgs[ 0 ] = programme;
// Do as much work as possible in the thread before dispatching to the UI thread for the simple UI work
Dispatcher.BeginInvoke( new InvokeProgrammeCellDelegate( AddProgrammeCellDelegate ), invokeArgs );
}
}
public delegate void InvokeProgrammeCellDelegate( Programme prog );
public void AddProgrammeCellDelegate( Programme prog )
{
Rectangle progCell = new Rectangle();
progCell.Fill = new SolidColorBrush( Color.FromArgb( 0xFF, (byte)( 0x13 ), (byte)( 0x45 ), (byte)( 0x70 ) ) );
progCell.Height = prog.UIHeight;
progCell.Width = prog.UIWidth;
progCell.SetValue( Canvas.TopProperty, prog.UITop );
progCell.SetValue( Canvas.LeftProperty, prog.UILeft );
ProgGrid.Children.Add( progCell );
ProgGrid.Width = Math.Max( ProgGrid.Width, prog.UIWidth + prog.UILeft );
}