将WPF控件名称绑定到不同的控件

时间:2017-05-05 14:41:11

标签: c# wpf xaml binding

拥有一系列按钮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>`

2 个答案:

答案 0 :(得分:1)

这是你想要做的事情的错误方法。这是“正确”的方式。这里有相当数量的样板代码,但你已经习惯了。

编写一个按钮viewmodel并为你的主视图模型提供一个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,用于显示按钮的“内容”,(因为样式中的边框覆盖了按钮本身的任何内容)。

你做的风格错了。非常非常错误。如果你告诉我风格,我可以帮你修理它。

答案 1 :(得分:0)

据我了解你想要的是修改&#34;文本&#34;按钮,我发现你可以这样做。

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