C# WPF-MVVM-从视图模型返回可绑定控件模板
我试图在列表视图上显示可用的Wifi网络(使用ManagedWifi SDK) 我已经在viewmodel中定义了WifiNetwork的ObservableCollection(包含名称、类型、信号强度(int)等),如下所示C# WPF-MVVM-从视图模型返回可绑定控件模板,c#,wpf,mvvm,C#,Wpf,Mvvm,我试图在列表视图上显示可用的Wifi网络(使用ManagedWifi SDK) 我已经在viewmodel中定义了WifiNetwork的ObservableCollection(包含名称、类型、信号强度(int)等),如下所示 public ObservableCollection<WifiNetwork> AvailableNetworks { get; set; } <ControlTemplate x:Key="Signal1"> <Canvas
public ObservableCollection<WifiNetwork> AvailableNetworks { get; set; }
<ControlTemplate x:Key="Signal1">
<Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/>
<Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ControlTemplate>
<ControlTemplate x:Key="Signal2">
<Canvas Width="32" Height="32" Canvas.Left="0" Canvas.Top="0">
<Rectangle Width="5.4375" Height="11.375" Canvas.Left="0.0937499" Canvas.Top="20.6563" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Rectangle Width="6.40625" Height="16" Canvas.Left="5.34375" Canvas.Top="16.0313" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FF37F307"/>
<Path Width="6.88835" Height="21.6562" Canvas.Left="11.75" Canvas.Top="10.375" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF" Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z "/>
<Rectangle Width="6.78126" Height="26.9687" Canvas.Left="18.5625" Canvas.Top="5.09376" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
<Rectangle Width="6.71874" Height="31.8437" Canvas.Left="25.2812" Canvas.Top="0.250002" Stretch="Fill" StrokeLineJoin="Round" Stroke="#FF000000" Fill="#FFFFFFFF"/>
</Canvas>
</ControlTemplate>
public observeCollection AvailableNetworks{get;set;}
我已经定义了控制模板(如1个绿色条和4个白色条,用于指示信号强度,这应该指向正确的方向:
<ItemsControl ItemsSource="{Binding AvailableNetworks }">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Rectangle Width="20" Height="{Binding SignalStrength,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Fill="{Binding Color,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></Rectangle>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我喜欢Darek的答案,但是如果您真的想使用这样的控制模板,您应该使用绑定到信号强度的样式和数据触发器,例如:
<Style TargetType="{x:Type MyControl}">
<Style.Triggers>
<DataTrigger Binding="{Binding SignalStrength}" Value="1">
<Setter Property="ControlTemplate" Value="{StaticResource Signal1}"/>
</DataTrigger>
<DataTrigger Binding="{Binding SignalStrength}" Value="2">
<Setter Property="ControlTemplate" Value="{StaticResource Signal2}"/>
</DataTrigger>
<!-- and so on -->
</Style.Triggers>
</Style>
另一种方法是在列表框上使用ItemTemplate并创建转换器类 创建名为ColorConverter的公共类,并在其中使用以下代码:
public class ColorConverter : IValueConverter
{
#region Implementation of IValueConverter
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
try
{
var val = System.Convert.ToInt32(value.ToString());
var param = System.Convert.ToInt32(parameter.ToString());
return val >= param ? Brushes.Green : Brushes.White;
}
catch
{
return Brushes.White;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
然后在带有列表框的页面上指定转换器:
<Window.Resources>
<Converters:ColorConverter x:Key="colorConverter" />
</Window.Resources>
然后使用上面的代码在listbox上创建一个DataTemplate,将绑定替换为正确的表单:
<ListBox Margin="0,73,0,0" ItemsSource="{Binding AvailableNetworks}">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Width="32"
Height="32"
Canvas.Left="0"
Canvas.Top="0">
<Rectangle Width="5.4375"
Height="11.375"
Canvas.Left="0.0937499"
Canvas.Top="20.6563"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=0}" />
<Rectangle Width="6.40625"
Height="16"
Canvas.Left="5.34375"
Canvas.Top="16.0313"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=20}" />
<Path Width="6.88835"
Height="21.6562"
Canvas.Left="11.75"
Canvas.Top="10.375"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=40}"
Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z " />
<Rectangle Width="6.78126"
Height="26.9687"
Canvas.Left="18.5625"
Canvas.Top="5.09376"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=60}" />
<Rectangle Width="6.71874"
Height="31.8437"
Canvas.Left="25.2812"
Canvas.Top="0.250002"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=80}" />
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
与前面提到的其他方法不同,这种方法的缺点是缺乏样式重用。鉴于您的视图模型不应该了解WPF,您的设计有一个更大的问题。
<ListBox Margin="0,73,0,0" ItemsSource="{Binding AvailableNetworks}">
<ListBox.ItemTemplate>
<DataTemplate>
<Canvas Width="32"
Height="32"
Canvas.Left="0"
Canvas.Top="0">
<Rectangle Width="5.4375"
Height="11.375"
Canvas.Left="0.0937499"
Canvas.Top="20.6563"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=0}" />
<Rectangle Width="6.40625"
Height="16"
Canvas.Left="5.34375"
Canvas.Top="16.0313"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=20}" />
<Path Width="6.88835"
Height="21.6562"
Canvas.Left="11.75"
Canvas.Top="10.375"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=40}"
Data="F1 M 12.2768,10.875L 18.1384,10.875L 18.1115,31.5313L 12.25,31.5313L 12.2768,10.875 Z " />
<Rectangle Width="6.78126"
Height="26.9687"
Canvas.Left="18.5625"
Canvas.Top="5.09376"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=60}" />
<Rectangle Width="6.71874"
Height="31.8437"
Canvas.Left="25.2812"
Canvas.Top="0.250002"
Stretch="Fill"
StrokeLineJoin="Round"
Stroke="#FF000000"
Fill="{Binding Strength, Converter={StaticResource colorConverter}, ConverterParameter=80}" />
</Canvas>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>