【问题标题】:Binding WPF Control Name to different Control将 WPF 控件名称绑定到不同的控件
【发布时间】:2017-05-05 14:41:10
【问题描述】:

具有一系列按钮 btn1、btn2、btn3 等的样式。

每个按钮的样式内部都有一个TextBlock,用于显示按钮的“内容”(因为样式内的边框覆盖了按钮本身的任何内容)。

现在,我希望将 TextBlock 名称绑定到按钮名称。例如 - btn1 的文本块的名称是 btn1Txt。这样做的目的是最终用户可以在设置菜单中为每个按钮分配自己的文本。

关于我将如何处理的任何提示?我承认我对 WPF 和绑定比较陌生。

编辑:::: 到目前为止,我有什么工作。

加载时,程序会检查每个按钮的文本设置文件。每个按钮的内容都被分配了适当的信息。然后在样式内部,我将 TextBlock Text 绑定到父按钮的内容。

这可能不是正常的处理方式,但它确实有效

方法

List<string> MainButtons = Properties.Settings.Default.MainButtonNames.Cast<string>().ToList();

        for (int i = 0; i < MainButtons.Count(); i++)
        {
            string actualNum = Convert.ToString((i + 1));
            var MainButtonFinder = (Button)this.FindName("MainButton" + actualNum);
            Console.WriteLine(MainButtonFinder.Name);
            MainButtonFinder.Content = MainButtons[i];
            Console.WriteLine(MainButtonFinder.Content);
        }

风格

<Style x:Key="MainButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="HorizontalAlignment" Value="Stretch"/>
        <Setter Property="Width" Value="100px"/>
        <Setter Property="MinHeight" Value="50"/>
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Border CornerRadius="20" Height="45" Width="100" Margin="0" Background="#FF99CCFF">
                        <TextBlock Text="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Content}" HorizontalAlignment="Center" VerticalAlignment="Center" FontFamily="LCARS" Foreground="White" Padding="5px" FontSize="18px" />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>`

【问题讨论】:

    标签: c# wpf xaml binding


    【解决方案1】:

    这是错误的方式来做你想做的事。这是做到这一点的“正确”方法。这里有相当多的样板代码,但你已经习惯了。

    编写一个按钮视图模型并为您的主视图模型提供一个 ObservableCollection:

    #region ViewModelBase Class
    public class ViewModelBase : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propName = null) =>
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
        #endregion INotifyPropertyChanged
    }
    #endregion ViewModelBase Class
    
    #region MainViewModel Class
    public class MainViewModel : ViewModelBase
    {
        public MainViewModel()
        {
            ButtonItems.Add(new ButtonItemViewModel("First Command", "First Item", () => MessageBox.Show("First Item Executed")));
            ButtonItems.Add(new ButtonItemViewModel("Second Command", "Second Item", () => MessageBox.Show("Second Item Executed")));
        }
    
        #region ButtonItems Property
        public ObservableCollection<ButtonItemViewModel> ButtonItems { get; }
            = new ObservableCollection<ButtonItemViewModel>();
        #endregion ButtonItems Property
    
    }
    #endregion MainViewModel Class
    
    #region ButtonItemViewModel Class
    public class ButtonItemViewModel : ViewModelBase
    {
        public ButtonItemViewModel(String cmdName, String text, Action cmdAction)
        {
            CommandName = cmdName;
            Text = text;
    
            Command = new DelegateCommand(cmdAction);
        }
    
        #region Text Property
        private String _text = default(String);
        public String Text
        {
            get { return _text; }
            set
            {
                if (value != _text)
                {
                    _text = value;
                    OnPropertyChanged();
                }
            }
        }
        #endregion Text Property
    
    
        #region CommandName Property
        private String _commandName = default(String);
        public String CommandName
        {
            get { return _commandName; }
            private set
            {
                if (value != _commandName)
                {
                    _commandName = value;
                    OnPropertyChanged();
                }
            }
        }
        #endregion CommandName Property
    
        public ICommand Command { get; private set; }
    }
    #endregion ButtonItemViewModel Class
    
    public class DelegateCommand : ICommand
    {
        public DelegateCommand(Action action)
        {
            _action = action;
        }
    
        private Action _action;
    
        public event EventHandler CanExecuteChanged;
    
        public bool CanExecute(object parameter)
        {
            return true;
        }
    
        public void Execute(object parameter)
        {
            _action?.Invoke();
        }
    }
    

    使 MainViewModel 成为您窗口的 DataContext

    public MainWindow()
    {
        InitializeComponent();
    
        DataContext = new MainViewModel();
    }
    

    以下是如何在 XAML 中将所有内容放在一起:

    <Grid>
        <StackPanel Orientation="Vertical">
            <GroupBox Header="Buttons">
                <ItemsControl ItemsSource="{Binding ButtonItems}" HorizontalAlignment="Left">
                    <ItemsControl.ItemTemplate>
                        <DataTemplate>
                            <Button
                                Margin="2"
                                MinWidth="80"
                                Content="{Binding Text}"
                                Command="{Binding Command}"
                                />
                        </DataTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </GroupBox>
    
            <GroupBox Header="Edit Buttons">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <ListBox 
                        Grid.Column="0"
                        Margin="2"
                        x:Name="ButtonEditorListBox"
                        ItemsSource="{Binding ButtonItems}" 
                        HorizontalAlignment="Left"
                        >
                        <ItemsControl.ItemTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock
                                        Margin="2"
                                        Text="{Binding CommandName}"
                                        />
                                    <TextBlock
                                        Margin="2"
                                        Text="{Binding Text, StringFormat=': &quot;{0}&quot;'}"
                                        />
                                </StackPanel>
                            </DataTemplate>
                        </ItemsControl.ItemTemplate>
                    </ListBox>
                    <ContentControl 
                        Grid.Column="1"
                        Margin="8,2,2,2"
                        Content="{Binding SelectedItem, ElementName=ButtonEditorListBox}"
                        >
                        <ContentControl.ContentTemplate>
                            <DataTemplate>
                                <StackPanel Orientation="Vertical">
                                    <TextBlock
                                        Margin="2"
                                        HorizontalAlignment="Stretch"
                                        FontWeight="Bold"
                                        Text="{Binding CommandName, StringFormat={}{0}: }"
                                        />
                                    <TextBox
                                        Margin="2"
                                        HorizontalAlignment="Stretch"
                                        Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}"
                                        />
                                </StackPanel>
                            </DataTemplate>
                        </ContentControl.ContentTemplate>
                    </ContentControl>
                </Grid>
            </GroupBox>
        </StackPanel>
    </Grid>
    

    回到你的问题:

    每个按钮的样式内部都有一个TextBlock,用于显示按钮的“内容”(因为样式内的边框覆盖了按钮本身的任何内容)。

    你做错了样式。非常非常错误。如果您向我展示样式,我可以帮助您解决它。

    【讨论】:

      【解决方案2】:

      据我了解,您想要修改按钮的“文本”,我想到您可以这样做。

      <Grid>
          <Grid.RowDefinitions>
              <RowDefinition Height="20"></RowDefinition>
              <RowDefinition></RowDefinition>
              <RowDefinition></RowDefinition>
          </Grid.RowDefinitions>
          <TextBox Text="{Binding ElementName=ButtonTest, Path=Content, UpdateSourceTrigger=PropertyChanged}" ></TextBox>
          <Button Name="ButtonTest" Grid.Row="1" Width="100" Height="40">
              <Button.ContentTemplate>
                  <DataTemplate>
                      <TextBlock Foreground="Blue" Text="{Binding}"></TextBlock>
                  </DataTemplate>
              </Button.ContentTemplate>
          </Button>
      </Grid>
      

      【讨论】:

      • 这与我实际发现的最接近。我猜。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 2012-08-18
      • 2011-07-26
      • 2011-01-06
      • 2021-08-10
      相关资源
      最近更新 更多