gpt4 book ai didi

c# - 如何动态生成必须放置在动态生成的组框内的切换按钮

转载 作者:太空宇宙 更新时间:2023-11-03 13:53:48 25 4
gpt4 key购买 nike

我是一名 C++ 开发人员,最近转向 C#。我正在开发处理动态生成组框的 WPF 应用程序。相应组框中的 RadioButton、togglebutton 等 UI 组件必须依次动态生成。

目前我有 2 个 xaml 文件 CodecView.xamlCodecWidgetView.xaml,两个 xaml 文件的单独 View 模型类。嗯,这个充满活力的一代很有趣,但对我来说肯定是一个棘手的情况。让我向您展示我动态生成一组组框的代码。

编解码器 View .xaml:

<UserControl.Resources>
<DataTemplate x:Key="CWDataTemplate">
<StackPanel>
<TextBlock Text="{Binding Description}" Margin="5,5,0,0"/>
<local:CodecWidgetView Margin="5,10,5,5"/>
</StackPanel>
</DataTemplate>
</UserControl.Resources>

<Grid Grid.Row="0" Style="{DynamicResource styleBackground}">
<Grid Name="NumberofCodecs" >
<ItemsControl ItemTemplate="{StaticResource CWDataTemplate}" ItemsSource="{Binding CodecWidgets}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Grid>
</Grid>

CodecWidgetView.xaml:

<Grid>
<GroupBox Height="Auto" HorizontalAlignment="Stretch" Margin="5,5,5,5" Name="groupBox1" VerticalAlignment="Stretch" Width="Auto">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton Name="MasterBox" Content="Master" Command="{Binding MasterCommand}" IsChecked="{Binding MasterCheck}" Grid.Column="1" Height="25" Width="50" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0" />
<ComboBox Grid.Column="2" ItemsSource="{Binding ModesList}" SelectedItem="{Binding SelectedModesList, Mode=OneWayToSource}" SelectedIndex="2" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox2" VerticalAlignment="Center" Width="80" />
<ComboBox Grid.Column="0" ItemsSource="{Binding FrequencyList}" SelectedItem="{Binding SelectedFrequencyList, Mode=OneWayToSource}" SelectedIndex="0" Height="23" HorizontalAlignment="Center" Margin="0,0,0,0" Name="comboBox1" VerticalAlignment="Center" Width="80" />
</Grid>

<Grid Grid.Row="1">
//Here I want to dynamically generate 4 radio buttons
</Grid>

<Grid Grid.Row="2">
<Label Name="BitDelay" Content="Bit Delay" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,205,0" Height="25" Width="55" />
<Slider Height="23" HorizontalAlignment="Center" Value="{Binding BitDelayValue, Mode=TwoWay}" Minimum="0.0" Maximum="255.0" TickFrequency="1.0" Margin="95,0,0,0" Name="bitdelayslider" VerticalAlignment="Center" Width="160" />
<TextBox Name="BitDelayValue" IsReadOnly="True" Text="{Binding ElementName=bitdelayslider,Path=Value, StringFormat=0.0}" Width="40" Height="20" Margin="0,0,110,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Grid>

<Grid Grid.Row="3">
<Label Name="DBGain" Content="DB Gain" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,205,0" Height="25" Width="55" />
<TextBox Name="DBGainValue" IsReadOnly="True" Text="{Binding ElementName=dbgainslider,Path=Value, StringFormat=0.0}" Width="40" Height="20" Margin="0,0,110,0" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Slider Height="23" HorizontalAlignment="Center" Value="{Binding DBGainValue, Mode=TwoWay}" Minimum="0.0" Maximum="59.5" TickFrequency="0.5" Margin="95,0,0,0" Name="dbgainslider" VerticalAlignment="Center" Width="160" />
</Grid>
</Grid>
</GroupBox>
</Grid>

CodecViewModel.cs:

public ObservableCollection<CodecWidgetViewModel> CodecWidgets { get; set; }

public CodecViewModel()
{
CodecWidgets = new ObservableCollection<CodecWidgetViewModel>();
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 8 - Dig Mic A" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 9 - Dig Mic B" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 10 - PCM A 3P3V" });
CodecWidgets.Add(new CodecWidgetViewModel { Description = "Location 11 - PCM B 3P3V" });
}

CodecWidgetViewModel.cs:

private string _description;
public string Description
{
get
{
return _description;
}

set
{
_description = value;
OnPropertyChanged("Description");
}
}

这在启动时给了我 4 个组框。现在这里是要求:

  1. 查看 CodecWidgetView.xaml,您会发现我添加了组合框、 slider 等,但在 Grid.Row=2 中,我想动态生成 4 个切换按钮内容为:16 位、20 位、24 位和 32 位
  2. 一旦发生这种情况,此按钮上必须只有一个单击事件,该事件设置切换状态并执行一些语句。

这是我在 C++ 中的做法:

//In Constructor
for(int jj = 0; jj < 4; jj++)
{
m_codecBitLengthButton[jj] = new ToggleButton(bitLengthes[jj]); //Here bitlength consists of 16Bit, 20Bit, 24Bit and 32Bit
m_codecBitLengthButton[jj]->setRadioGroupId(55); // make a custom group ID
addAndMakeVisible(m_codecBitLengthButton[jj]);
m_codecBitLengthButton[jj]->addButtonListener(this);
m_codecBitLengthButton[jj]->setToggleState(false, false);
}
// check which button should be pressed
cmd = (0x9400 | (m_slot & 0xFF));
m_msp430->ReadInternalCommand(cmd, 1, readBuf); //This returns some value in readBuf
m_bitLength = readBuf[0];
m_codecBitLengthButton[readBuf[0]]->setToggleState(true, false); //Togglestate set to true on startup based on readBuf[0]


//Gets called when any of the toggle button is clicked
while(jj < 4)
{
if(button == m_codecBitLengthButton[jj])
{
// add code for bit length support
cmd = ((CODEC_LENGTH_CMD & 0x7F00) | (m_slot & 0xFF));
sendBuf[numBytes++] = jj; // this should represent the proper number of bits
m_bitLength = jj;
break;
}
jj++;
}

如何在 C# 中实现相同的目的? :)

最佳答案

你可以用命令来做到这一点:

CodecWidgetView.xaml:

<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ToggleButton Grid.Column="0" Content="16Bit" Command="{Binding Path=ToogleButtonCommand}" CommandParameter="16"/>
<ToggleButton Grid.Column="1" Content="20Bit" Command="{Binding Path=ToogleButtonCommand}" CommandParameter="20"/>
<ToggleButton Grid.Column="2" Content="24Bit" Command="{Binding Path=ToogleButtonCommand}" CommandParameter="24"/>
<ToggleButton Grid.Column="3" Content="32Bit" Command="{Binding Path=ToogleButtonCommand}" CommandParameter="32"/>
</Grid>

这将以 mvvm 方式变得非常简单。

好处是您可以指定 CommandParameter 将是哪个参数。在示例中,我对其进行了硬编码,但它也可以绑定(bind)。

CodecWidgetViewModel.cs:

    RelayCommand _toogleButtonCommand;
public ICommand ToogleButtonCommand
{
get
{
if (_toogleButtonCommand == null)
{
_toogleButtonCommand = new RelayCommand(this.DoSomethingExecute,
this.DoSomethingCanExecute);
}
return _toogleButtonCommand;
}
}

public void DoSomethingExecute(object param)
{
int result = Convert.ToInt32(param);

if (result == 16)
{
//To this and so on for example
}
}

希望这对您有所帮助。

编辑:要随时定义哪个按钮 IsChecked,请在您的 ViewModel 中绑定(bind) ToogleButtons IsChecked 属性和 ToogleButton 值的属性。

private bool _isCheckedToogle1;
public bool IsCheckedToogle1
{
get { return _isCheckedToogle1; }
set
{
_isCheckedToogle1 = value;
OnPropertyChanged("IsCheckedToogle1");
}
}

private int _toogleButton1Value = 16;
public int ToogleButton1Value
{
get { return _toogleButton1Value; }
set
{
_toogleButton1Value = value;
OnPropertyChanged("ToogleButton1Value");
}
}

XAML:

<ToggleButton Grid.Column="0" x:Name="toogleButton1" Content="16Bit" Command="{Binding Path=ToogleButtonCommand}" IsChecked="{Binding Path=IsCheckedToogle1}" >
<ToggleButton.CommandParameter>
<MultiBinding Converter="{StaticResource Converter}">
<Binding Path="ToggleButton1Value" />
<Binding />
</MultiBinding>
</ToggleButton.CommandParameter>
</ToggleButton>

因为它现在是一个 MutliBinding,所以您需要一个转换器和一个类作为参数的新值:

    public object Convert(object[] values, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
ToggleValue val = new ToggleValue();
val.View = values[1] as CodecWidgetViewModel;
val.Value = System.Convert.ToInt32(values[0]);
return val;
}

public object[] ConvertBack(object value, Type[] targetTypes, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();

}
}

public class ToggleValue
{
public int Value { get; set; }
public CodecWidgetViewModel View { get; set; }
}

还有你的新 CommandLogik

    public void DoSomethingExecute(object param)
{
ToggleValue result = param as ToggleValue;

if (result.Value == 16)
{
result.View.IsCheckedToogle1 = true;
result.View.IsCheckedToogle2 = false;
result.View.IsCheckedToogle3 = false;
result.View.IsCheckedToogle4 = false;
}
}

关于c# - 如何动态生成必须放置在动态生成的组框内的切换按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12952957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com