2016-02-01 3 views
1

У меня возникли проблемы с моим приложением C# UWP.UWP transparent LinearGradientBrush

<Grid VerticalAlignment="Bottom" Height="40" Grid.Row="3" Margin="0,0,0,-1"> 
    <Grid.Background> 
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> 
     <GradientStop Color="#00000000" Offset="0"/> 
     <GradientStop Color="{StaticResource stdBackgroundColor}" Offset="1"/> 
    </LinearGradientBrush> 
    </Grid.Background> 
</Grid> 

Этот фрагмент кода должен показать прозрачную накладку в нижней части страницы, но вместо этого он создает черновато накладку, как это добавляет прозрачные значения на верхней части существующего фона (который является также цвета stdBackgroundColor) и, следовательно, выглядит довольно странно (см рисунок ниже)

Overlay problem

Как я могу добиться прозрачного наложения к контенту (например, как ScrollViewer) без этого эффекта?

+0

Это выглядит немного смешно, и я не уверен, что я визуализую ваш намеченный выход. Поскольку у вас есть ваш альфа-набор в 0 на вашем первом смещении, и я не уверен, что такое stdBackgroundColor, есть ли у вас пример того, каким будет ваш желаемый эффект? –

+0

Ожидаемый результат на картинке должен быть, что ничего не видно, но все то же самое «Цвет» (в данном случае это stdBackgroundColor, который является # FFa1a1a1). Когда содержание позади Сетки сверху, это содержимое должно постепенно исчезать в цвет фона (stdBackgroundColor). – user3079834

ответ

2

Отказ от ответственности, я нахожусь на работе, и у меня нет доступа к платформе, в которой я могу протестировать этот код, но из того, что я искал, он должен работать.

Основная проблема - это сочетание цветов, а именно то, что мы хотим плавно смешивать с полной альфой до любого произвольного цвета. Проблема с запуском с Color.Transparent заключается в том, что вы получите полосу белого цвета, в то время как альфа-канал прогрессирует больше, чем другие компоненты. Аналогичная проблема возникает с #00000000, так как у нее есть полоса черного цвета. Решение состоит в том, чтобы начать с версии вашего цвета, которая имеет непрозрачность, установленную на 0. Как мы это понимаем, немного отличается от того, какая версия приложения на основе XAML вы разрабатываете, и мне трудно держать их прямолинейными. В UWP у нас нет маски непрозрачности, и мы не можем создать градиент только для непрозрачности. Остается только использовать IValueConverter.

Color недвижимость в GradientStop является Color и не Brush, поскольку это слишком усложнит систему рендеринга. Таким образом, первый шаг, который нужно это IValueConverter, который принимает любые Color и полосы из альфа-значение:

public class TransparentColorConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
          object parameter, string language) 
    { 
     Color convert = (Color) value; // Color is a struct, so we cast 
     return Color.FromArgb(0, convert.R, convert.G, convert.B); 
    } 

    public object ConvertBack(object value, Type targetType, 
           object parameter, string language) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Следующая задача состоит в том, чтобы создать привязку, что мы можем использовать этот цвет против. Объект привязки позволяет нам указать Source, который может быть любым объектом, который мы передаем. ElementName не будет работать, потому что ресурсы ссылаются на ключ, а не на имя.

<LinearGradientBrush x:Key="OpacityGradientBrush" StartPoint="0,0" EndPoint="0,1"> 
    <GradientStop Color="{Binding Source={StaticResource stdBackgroundColor}, 
         Converter={StaticResource TransparentColorConverter}}" Offset="0"/> 
    <GradientStop Color="{StaticResource stdBackgroundColor}" Offset="1"/> 
</LinearGradientBrush> 

Конечно, не забудьте поставить TransparentColorConverter в вашем Resources, так что вы можете ссылаться на него здесь. Лично я бы предпочел не использовать конвертеры, но в этом случае я считаю, что это оправданно.

ПРИМЕЧАНИЕ: В привязке используется Source, поэтому мы можем ссылаться на статический ресурс. Если бы у нас было свойство, с которым мы могли бы связываться, мы могли бы использовать вместо него Path.


Ответ ниже действителен для WPF, но не UWP. Я желаю Microsoft прекратит переопределение ту же концепцию в несовместимых способов, но это мир, в котором мы живем.

исправляющие мой ответ основан на this answer

Вы хотите изменить свой LinearGradientBrush использовать свойство непрозрачности, а не цвет #00000000. Проблема состоит в том, что он интерполируется от черного до желаемого цвета.Чтобы получить аффект вы хотите, вы должны будете создать маску непрозрачности кисти, как это:

<LinearGradientBrush x:Key="OpacityGradientBrush" StartPoint="0,0" EndPoint="0,1"> 
    <GradientStop Color="#00FFFFFF" Offset="0"/> 
    <GradientStop Color="#FFFFFFFF" Offset="1"/> 
</LinearGradientBrush> 

Тогда в коде вам необходимо применить маску непрозрачности, чтобы вы ссылаться на него, как это:

<Grid VerticalAlignment="Bottom" Height="40" Grid.Row="3" 
    Background="{StaticResource stdBackgroundColor}" 
    OpacityMask="{StaticResource OpacityGradientBrush} Margin="0,0,0,-1"/> 

Проблема в том, что если вы хотите, чтобы смесь влияла только на непрозрачность, остальная часть цвета должна быть одинаковой. В противном случае вы получите полосу вашего начального цвета и измените цвет до конца.

+0

Это звучит разумно, но, к сожалению, я получаю сообщение об ошибке, что 'Свойство 'непрозрачность' не было найдено в типе 'GradientStop'. \t ', так как вы реализовали' непрозрачность' в 'LinearGradientBrush'? – user3079834

+0

Я изменил код, чтобы обеспечить тот же эффект, но не использовать непрозрачность в градиентной остановке. Надеюсь, это сработает для вас. Комментарии о цветовом смешении все еще применяются, и я не изменил их. –

+1

Несчастливо ответ, вы связаны с только для WPF, но не для приложений C# UWP. В UWP нет «OpacityMask» (пока) – user3079834

 Смежные вопросы

  • Нет связанных вопросов^_^