0

私は C++ 開発者で、最近 C# に移行しました。ボタン、テキストボックスなどの Ui コンポーネントを動的に生成する必要がある WPF アプリを開発しています。これが私が今までやってきた方法です。

XAML クラス:

<Grid Visibility="{Binding IsAvailable, Converter={StaticResource booltovisibility}}">
    <Grid.Resources>
        <convert:BooleanToVisibilityConverter x:Key="booltovisibility"/>
    </Grid.Resources>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="170" />
        <ColumnDefinition />
        <ColumnDefinition Width="130" />
        <ColumnDefinition Width="115" />
    </Grid.ColumnDefinitions>
    <Label Grid.Column="0" Content="{Binding ChannelName}" Height="25" Width="120" Name="VoltageLabel" Margin="20,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" />
    <TextBox Grid.Column="1" Text="{Binding VoltageText}" Height="25" Width="65" Name="VoltageBox" Margin="0,0,80,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <Button Grid.Column="1" Content="Set" CommandParameter="{Binding VoltageText}" Command="{Binding VoltageCommand}" Height="25" Width="65" Name="VoltageSetbtn" Margin="80,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <Label Grid.Column="2" Content="{Binding CurrentText}"  Height="25" Width="40" Name="CurrentLabel" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
    <ToggleButton Grid.Column="3" Content="On"  Height="25" Width="30" Name="VoltageToggleBtn" Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>

<Button Content="Bavaria" Name="BavariaBtn" Click="BavariaBtn_Click" />

ViewModel クラス:

public List<VoltageBoardChannel> channelList = null;       

    public List<VoltageBoardChannel> bavaria2Channels = new List<VoltageBoardChannel>
    {
         new VoltageBoardChannel { ChannelName = "VDD__MAIN", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__IO__AUD", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__CODEC__AUD", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand},
         new VoltageBoardChannel { ChannelName = "VDD__DAL__AUD", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__DPD__AUD", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__PLL__AUD", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },        
         new VoltageBoardChannel { ChannelName = "", IsAvailable = false, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "", IsAvailable = false, VoltageText = String.Empty, VoltageCommand = m_voltageCommand }
    };

    private ICommand m_voltageCommand;        

    public List<VoltageBoardChannel> bavaria1Channels = new List<VoltageBoardChannel>
    {
         new VoltageBoardChannel { ChannelName = "", IsAvailable = false, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "", IsAvailable = false, VoltageText = String.Empty, VoltageCommand = m_voltageCommand }
         new VoltageBoardChannel { ChannelName = "VDD__MAIN", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__IO", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__CODEC", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__LDO", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand },
         new VoltageBoardChannel { ChannelName = "VDD__AMP", IsAvailable = true, VoltageText = String.Empty, VoltageCommand = m_voltageCommand }             
    };            

    public VoltageViewModel()
    {
        channelList = new List<VoltageBoardChannel>(0);
        channelList = bavaria1Channels;            
        m_voltageCommand = new DelegateVoltageCommand(x => SetCommandExecute(x));
    }

    public List<VoltageBoardChannel> VoltageChannelList
    {
        get 
        { 
            return channelList; 
        }

        set
        { 
            channelList = value;
            OnPropertyChanged("ChannelList");
        }
    }        

    public void SetCommandExecute(object voltageText)
    {
        Debug.WriteLine(voltageText);
    }

モデル クラス:

private string mChannelName;
    public string ChannelName
    {
        get; set;
    }

    private bool mIsAvailable;
    public bool IsAvailable
    {
        get; set;
    }

    string voltageText = string.Empty;
    public string VoltageText
    {
        get; set;
    }

    string currentText = "0 V";
    public string CurrentText
    {
        get; set;
    }

    public ICommand VoltageCommand { get; set; }

XAml.cs:

 VoltageViewModel mVoltageViewModel = new VoltageViewModel();

    public VoltageView()
    {
        InitializeComponent();
        this.DataContext = mVoltageViewModel;

        OnChildAdd();
    }
public void OnChildAdd() //Constructor
    {   
        VoltageViewModel mVoltageViewModel = new VoltageViewModel();         
        foreach (VoltageBoardChannel mVoltageChannelViewModel in mVoltageViewModel.VoltageChannelList)
        {
            VoltageChannelView mVoltageChannelView = new VoltageChannelView();
            mVoltageChannelView.Margin = new Thickness(2);
            mVoltageChannelView.ChannelInfo = mVoltageChannelViewModel;
            // Some Code
        }
    }

ここでは、バイエルン 1 のすべてのチャンネルが表示されますavailable = false。したがって、false の場合、テキストボックス、ボタン、ラベル、トグルボタンが表示されます。チャンネル名は「」です。私は次のことを達成したい:

ここには、bavaria 1 と bavaria 2 の 2 つのチャネルがあります。起動時に、bavaria1 は既に表示されています。ここでは、使用可能なチャネルを確認し、それらのみを起動時にビューに追加します。つまり、available = true表示する必要がありavailable = false、対応する要素を表示しないようにする必要があります。現在available = false、ラベル以外のボタン、テキストボックス、トグルボタンでも表示されます(チャンネル名は「」になります)。どうすればそれを達成できますか?

4

2 に答える 2

1

要素の Visibility プロパティはブール フィールドではないため、ブール バインディングを使用して XAML で要素を非表示にするには、要素を変換する必要があります。

<ListBox ItemsSource="{Binding VoltageChannelList}">
  <ListBox.Resources>
    <BooleanToVisibilityConverter x:Key="booltovisibility"/>
  </ListBox.Resources>
  <Grid Visibility="{Binding IsAvailable,
                     Converter={StaticResource booltovisibility}}">
     <!-- controls -->
  </Grid>
</ListBox>

デフォルトのBooleanToVisibilityコンバーターを使用します。


そうは言っても、おそらく VoltageChannelList をObservableCollectionに変更して、アイテムを挿入または削除すると、変更がビューに反映されるようにする必要があります。

また、autoproperties を使用する場合は、バッキング フィールドを作成しないことに注意してください。

private bool mIsAvailable; // this is not used by the property below
public bool IsAvailable { get; set; }

このコードを使用する場合、mIsAvailable は独自のバッキング フィールドを作成するため、IsAvailable の呼び出しから返されることはありません。

于 2012-10-15T12:18:48.830 に答える
1

次のようなプロパティを作成するようなことができます。

List<VoltageChannel> AvailableChannels {
  get
  {
     var returned = new List<VoltageChannel>();
     foreach (VoltageChannel vc in VoltageChannelList)
     {
        if (vc.IsAvailable)
          returned.add(vc);
     }
     return vc;
  }
}

次に、おそらく次のような ItemsControl を使用して、ビューをこのプロパティにバインドします。

<ItemsControl Name="_itemsControl"  ItemsSource="{Binding AvailableChannels}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate><WrapPanel />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      ... (your XAML to show the channels) ...
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

(コードをテストしませんでした)

于 2012-10-15T12:18:14.780 に答える