Решарпер говорит, что член набора OnPropertyChange может быть закрытым, хотя это не так - PullRequest
3 голосов
/ 03 марта 2012

Я использую C #, MVVM, WPF и Resharper.

При использовании следующего кода:

    public bool CombiBanksSelected
    {
        get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
        set
        {

Я получаю предупреждение от Resharper: сделать доступным набор доступа.

Когда я делаю метод set закрытым, я получаю InvalidOperationException: привязка TwoWay или OneWayToSource не может работать с доступным только для чтения свойством '' CombiBanksSelected '' типа '' PcgTools.ViewModels.PcgViewModel. '

Конечно, я могу подавить это, добавив:

    public bool CombiBanksSelected
    {
        get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
// ReSharper disable MemberCanBePrivate.Global
        set
// ReSharper restore MemberCanBePrivate.Global
        {

Но это выглядит не очень хорошо и не очень хорошо. Есть ли лучшая альтернатива или решение этой проблемы?

В соответствии с ответом я должен изменить код XAML. Мой это:

<UserControl x:Class="PcgTools.PcgWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:PcgTools.ViewModels" Height="Auto" Width="Auto" 
    Loaded="Window_Loaded">

<Grid>
  ...
    <RadioButton Content="_Programs" Height="16" HorizontalAlignment="Left" Margin="12,12,0,0" Name="radioButtonPrograms" VerticalAlignment="Top" 
                 IsChecked="{Binding Path=ProgramBanksSelected}" IsEnabled="{Binding Path=ProgramsEnabled}"/>
    <RadioButton Content="_Combis" Height="16" HorizontalAlignment="Left" Margin="85,12,0,0" Name="radioButtonCombis" VerticalAlignment="Top" 
                 IsChecked="{Binding Path=CombiBanksSelected}"  IsEnabled="{Binding Path=CombisEnabled}"/>

У меня проблема Resharper для обоих (и более) свойств, связанных с IsChecked (ProgramBanksSelected и CombiBanksSelected в приведенном выше коде).

В ответе показано, что я должен использовать DataTemplate, но я все еще не могу понять, как именно (без использования локатора MVVM light).

Как использовать контекст данных / шаблон?

Ответы [ 3 ]

9 голосов
/ 04 марта 2012

У Resharper недостаточно информации, чтобы определить, используется ли сеттер. Например:

Этот код:

public partial class Page2
{
    public Page2()
    {
        InitializeComponent();

        DataContext = new List<ViewModel>
                          {
                              new ViewModel()
                          };
    }
}

public class ViewModel : ViewModelBase
{
    private bool _combiBanksSelected;
    public bool CombiBanksSelected
    {
        get { return _combiBanksSelected; }
        set
        {
            Set(()=>CombiBanksSelected, ref _combiBanksSelected, value);
        }
    }
}

с этим Xaml:

<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="Template" >
            <CheckBox IsChecked="{Binding CombiBanksSelected}"/>
        </DataTemplate>
    </Grid.Resources>
    <ListBox ItemsSource="{Binding}" ItemTemplate="{StaticResource Template}" />
</Grid>

покажет, что сеттер не используется (когда SWA включен).

Однако, если вы измените Xaml (добавив DataType = "{x: Type Samples: ViewModel}" ) на:

<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="Template" DataType="{x:Type Samples:ViewModel}">
            <CheckBox IsChecked="{Binding CombiBanksSelected}"/>
        </DataTemplate>
    </Grid.Resources>
    <ListBox ItemsSource="{Binding}" ItemTemplate="{StaticResource Template}" />
</Grid>

R # теперь имеет достаточно информации и не отображает предупреждение.

Конечно, есть и другие способы дать R # и VS Intellisense больше подсказок о типах, которые вы используете. Примеры:

Использование локатора вида MVVM Light:

<UserControl ...
    DataContext="{Binding AViewModel, Source={StaticResource Locator}}" />

Использование d: DataContext. Я рекомендую посмотреть это MSDN прохождение

<UserControl ...
    d:DataContext="{d:DesignInstance AViewModel, IsDesignTimeCreatable=true}"

Явная установка DataContext

<UserControl.Resources>
    <AViewModel x:Key="theModel/>
</UserControl.Resources>

<Grid DataContext="{StaticResource theModel}"> ...

и т.д ...

Любой из этих методов позволяет R # и VS выводить использование типов и предоставлять intellisense.

3 голосов
/ 04 марта 2012

В дополнение к прекрасным советам Фила вы также можете использовать атрибут UsedImplicitlyAttribute. Вы можете использовать Nuget, чтобы добавить DLL для вас

enter image description here

И тогда R # сам предложит украсить сеттер атрибутом:

public bool CombiBanksSelected
{
    get { return _selectedBanksType == ESelectedBanksType.CombiBanks; }
    [UsedImplicitly] set
    {

Я считаю его менее шумным, чем комментарий, и хорошо подходит для ViewModel, где понимается, что привязки данных обычно неизвестны R #. (иногда я предпочитаю комментарий, напоминающий мне, почему я хотел, чтобы R # заткнулся, но не в этом случае).

Приветствия
Berryl

2 голосов
/ 04 марта 2012

resharper - отличный инструмент ... но иногда он может ошибаться.

Вы не должны комментировать свой исходный код с комментариями, пожалуйста, уточните.Или любой другой инструмент по этому вопросу.Инструмент неправильный, поэтому не исправляйте код, исправьте инструмент.

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

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