我试图根据机器状态(关/开)设置的布尔变量的值在多个网格中显示红色或绿色图标。转换器是实现此目的的最佳方式吗?我遇到了将我的变量绑定到网格上的图像字段的麻烦。我似乎无法解雇我的booltoimageconverter类? 感谢您的任何指导。
答案 0 :(得分:4)
使用BoolToImageConverter。使用此代码时,请检查所有资源和路径。 (图像,转换器,模型(用于模型和转换器检查命名空间))。
<强>演示:强> 在本演示中,我使用名称 Flag 更改了属性,然后BoolToImageConverter读取此属性并创建了BitmapImage。
<强> App.xaml中:强>
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:converters"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<conv:BoolToImageConverter x:Key="BoolToImageConv" />
</ResourceDictionary>
</Application.Resources>
<强> MainWindow.xaml:强>
<Grid x:Name="LayoutRoot">
<!--Image for demonstration, with binding-->
<Image x:Name="TargetImageBlock" Source="{Binding Flag, Converter={StaticResource BoolToImageConv}}" VerticalAlignment="Top" HorizontalAlignment="Left" Height="100" Width="100"/>
<!--Button for changing property in view model-->
<Button Content="Change" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="15" Padding="15" Click="Button_Click"/>
</Grid>
<强> MainWindow.cs:强>
public partial class MainWindow : Window
{
// create some view model
SomeModel model = new SomeModel();
public MainWindow()
{
InitializeComponent();
Loaded += MainWindow_Loaded;
}
void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Loaded -= MainWindow_Loaded;
// set context
this.DataContext = model;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// change property in view model (not image)
if (model.Flag)
model.Flag = false;
else
model.Flag = true;
}
}
<强> SomeModel.cs:强>
public class SomeModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool _flag = false;
/// <summary>
/// This flag is your bool value.
/// </summary>
public bool Flag
{
get { return _flag; }
set
{
if (_flag != value)
{
_flag = value;
Notify();
}
}
}
private void Notify([CallerMemberName] string name = "")
{
var h = PropertyChanged;
if (h != null)
h(this, new PropertyChangedEventArgs(name));
}
}
<强> BoolToImageConverter:强>
namespace converters
{
public class BoolToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
bool val = (bool)value;
if (val)
{
return new BitmapImage(new Uri("/images/like.png", UriKind.RelativeOrAbsolute));
}
else
{
return new BitmapImage(new Uri("/images/favs.png", UriKind.RelativeOrAbsolute));
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
答案 1 :(得分:2)
价值转换器可行。肯定。
尽管如此,我觉得所有与程序外观有关的内容都应该存在于xaml中。这就是它的设计方式。
想想如果用户想为你的网格选择颜色主题怎么办?使用转换器,您可能需要做一些黑客才能完成任务。但是对于样式它更自然 - 你只需要编写一个新的并动态设置它。
我即将展示基于触发器的解决方案。它设置颜色,但使用图像也是一样的。
的Xaml:
<Window x:Class="Wpf1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style x:Key="ColorfulTextBlock" TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsGreen}" Value="True">
<Setter Property="Background" Value="Green" ></Setter>
</DataTrigger>
<DataTrigger Binding="{Binding IsGreen}" Value="False">
<Setter Property="Background" Value="Red" ></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<TextBlock Style="{StaticResource ColorfulTextBlock}">
Color is changed when checbox is clicked
</TextBlock>
<CheckBox IsChecked="{Binding IsGreen}"></CheckBox>
</StackPanel>
</Window>
代码背后(只是原始分配vm,可以通过xaml完成)
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext =new MainVm();
}
}
ViewModel
public sealed class MainVm : DependencyObject
{
public static readonly DependencyProperty IsGreenProperty =
DependencyProperty.Register("IsGreen", typeof (bool), typeof (MainVm), new PropertyMetadata(default(bool)));
public bool IsGreen
{
get { return (bool) GetValue(IsGreenProperty); }
set { SetValue(IsGreenProperty,value); }
}
}