WPF MaterialDesignInXamlToolkit Snackbar为每条消息提供不同的样式



如何更改不同消息的样式(例如背景/前景颜色(?我想显示不同样式的Success、Info和Error消息。

我试着使用绑定这样的转换器:

XAML:

<materialDesign:Snackbar
x:Name="MainSnackbar"
Grid.Row="0"
HorizontalAlignment="Center"
ActionButtonPlacement="Inline"
Background="{Binding MessageQueueType, Converter={StaticResource StatusToMessageBackgroundColorConverter}, UpdateSourceTrigger=PropertyChanged}"
Foreground="{Binding MessageQueueType, Converter={StaticResource StatusToMessageForegroundColorConverter}, UpdateSourceTrigger=PropertyChanged}"
MessageQueue="{Binding MessageQueue}" />

转换器C#:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
switch ((MessageQueueStatus)value)
{
case MessageQueueStatus.Error:
return new SolidColorBrush(Colors.DarkRed);
case MessageQueueStatus.Info:
return new SolidColorBrush(Colors.DimGray);
case MessageQueueStatus.Sucess:
return new SolidColorBrush(Colors.ForestGreen);
}
return null;
}

VM C#:

private void ShowSnackMessage(string message, MessageQueueStatus messageQueueType, bool ClearOtherMessages = false)
{
if(ClearOtherMessages)
MessageQueue.Clear();
MessageQueueType = messageQueueType;
MessageQueue.Enqueue(message);
}

但是,如果一次排队的消息类型超过1种,则只应用最后选择的"样式"。如果我先将"Info"消息排队而不是将"Success"消息排队,则两者都将显示为"Success-style"。

我实现了我想要的,在XAML中直接创建了3个不同的Snackbar,并设置了不同的样式,在VM中创建了3种不同的MessageQueues。但通过这种方式,我需要为我需要的每种样式创建一个不同的对象和队列。这是唯一的方法吗?

我们做了一个技巧,在不需要多个小吃店的情况下实现这种行为。

这个想法是将小吃店中排队的消息列表保存在一个单独的列表中,当从小吃店中删除一条消息时(就在放入下一条消息之前(,我们会在包含选择颜色的信息的属性上触发来更改小吃店的背景色。

我们在xaml 中的小吃条

<materialDesign:Snackbar Name="MainSnackbar" ActionButtonStyle="{StaticResource SnackActionButton}" Grid.Row="2" Grid.ColumnSpan="2" MessageQueue="{Binding MessageQueue}" Message="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center">
<utilities:TreeHelpers.Modifiers>
<utilities:ModifierCollection >
<utilities:Modifier TemplatePartName="ContentBorder" Property="{x:Static Border.CornerRadiusProperty}" Value="20 20 0 0">
</utilities:Modifier>
</utilities:ModifierCollection>
</utilities:TreeHelpers.Modifiers>
<materialDesign:Snackbar.Style>
<Style TargetType="materialDesign:Snackbar" BasedOn="{StaticResource {x:Type materialDesign:Snackbar}}">
<Setter Property="Background" Value="{StaticResource MaterialDesignSnackbarBackground}"></Setter>
<Setter Property="MaxWidth" Value="{Binding ActualWidth, ElementName=AppGrid}" />
<Style.Triggers>
<DataTrigger  Binding="{Binding CurrentMessageLevel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="1">
<Setter Property="Background" Value="{StaticResource FwBrushError}"></Setter>
</DataTrigger>
<DataTrigger  Binding="{Binding CurrentMessageLevel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="2">
<Setter Property="Background" Value="{StaticResource FwBrushWarning}"></Setter>
</DataTrigger>
<DataTrigger  Binding="{Binding CurrentMessageLevel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="3">
<Setter Property="Background" Value="{StaticResource FwBrushInfo}"></Setter>
</DataTrigger>
<DataTrigger  Binding="{Binding CurrentMessageLevel, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="4">
<Setter Property="Background" Value="{StaticResource FwBrushSuccess}"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</materialDesign:Snackbar.Style>
</materialDesign:Snackbar>

我们将消息排入队列的部分


public class MessageToSnack
{
public string Content { get; set; } = "";
public MessageToSnackLevel Level { get; set; } = 0;
public TimeSpan? Duration { get; set; } = null; // if null it will use the default duration of material design -> 3s
public bool WithCloseButton { get; set; } = true;
}
public enum MessageToSnackLevel
{
NoLevel = 0,
Error = 1,
Warning = 2,
Info = 3,
Success = 4,
}
private void EventSnackMessageReceived(MessageToSnack snakMsg)
{
_snackedMessages.Add(snakMsg);
if (snakMsg.WithCloseButton)
{
MessageQueue.Enqueue(snakMsg.Content, new PackIcon() { Kind = PackIconKind.Close}, (queue) => CloseCommand(queue), MessageQueue, false, false, snakMsg.Duration);
}
else
{
MessageQueue.Enqueue(snakMsg.Content, null, null, null, false, false, snakMsg.Duration);
}
}

管理CurrenMessageLevel属性的部分

List<MessageToSnack> _snackedMessages = new List<MessageToSnack>(); // used when intercepting a snackbar message poping , to find its reference and be able to change the color with a trigger on the CurrentLevel
private SnackbarMessage _message;
public SnackbarMessage Message
{
get { return _message; }
set 
{ 
SetProperty(ref _message, value);
if (_message != null)
{
var localMessage = _snackedMessages.FirstOrDefault(m => m.Content.Equals(_message.Content.ToString()));
if (localMessage != null)
{
CurrentMessageLevel = localMessage.Level;
_snackedMessages.Remove(localMessage);
}
else
{
CurrentMessageLevel = 0;
}
}
else
{
CurrentMessageLevel = 0;
}
}
}
private MessageToSnackLevel _currentMessageLevel;
public MessageToSnackLevel CurrentMessageLevel
{
get { return _currentMessageLevel; }
set { SetProperty(ref _currentMessageLevel, value); }
}

相关内容

  • 没有找到相关文章

最新更新