WPF - MVVM - вернуть шаблон привязываемого элемента управления из модели представления - PullRequest
3 голосов
/ 09 мая 2011

Я пытаюсь отобразить доступные сети Wifi (используя ManagedWifi SDK) в виде списка.

Я определил ObservableCollection WifiNetwork (содержит имя, тип, уровень сигнала (int) и т. Д.) В моей модели просмотра, как показано ниже

public ObservableCollection<WifiNetwork> AvailableNetworks { get; set; }

Я определил шаблоны управления (например, 1 зеленая полоса и 4 белые полосы для обозначения уровня сигнала <= 20%, 2 зеленые полоски и 3 белые полосы для указания уровня сигнала в диапазоне от 20 до 40% и т. Д.) В Приложениях приложения в приложении. xaml как показано ниже </p>

<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>

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

Мне, вероятно, нужно какое-то преобразование из Signal Strength (int) в шаблон Control.

Какие-либо предложения / примеры кода для решения этой задачи?

Ответы [ 3 ]

1 голос
/ 09 мая 2011

Мне нравится ответ Дарека, но если вы действительно хотите использовать подобные шаблоны управления, вы должны использовать стиль и триггер данных, привязанный к силе сигнала, например ::10000

<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>
1 голос
/ 09 мая 2011

Это должно вести в правильном направлении:

    <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>
0 голосов
/ 09 мая 2011

Другой подход заключается в том, чтобы просто использовать 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
}

Затем на странице со списком ListBox назначьте конвертер:

<Window.Resources>
    <Converters:ColorConverter x:Key="colorConverter" />
</Window.Resources>

Убедитесь, что вы поместили пространство имен для «Конвертеры» в верхней части xaml:

xmlns:Converters="clr-namespace:ProjectNameHere"

Затем создайте 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>

Недостатком такого подхода является отсутствие повторного использования стилей, в отличие от других упомянутых методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...